Design pattern for an ASP.NET project using Entity Framework
Posted
by
MPelletier
on Programmers
See other posts from Programmers
or by MPelletier
Published on 2013-11-06T20:41:21Z
Indexed on
2013/11/06
22:07 UTC
Read the original article
Hit count: 363
I'm building a website in ASP.NET (Web Forms) on top of an engine with business rules (which basically resides in a separate DLL), connected to a database mapped with Entity Framework (in a 3rd, separate project).
I designed the Engine first, which has an Entity Framework context, and then went on to work on the website, which presents various reports. I believe I made a terrible design mistake in that the website has its own context (which sounded normal at first).
I present this mockup of the engine and a report page's code behind:
Engine (in separate DLL):
public Engine
{
DatabaseEntities _engineContext;
public Engine()
{
// Connection string and procedure managed in DB layer
_engineContext = DatabaseEntities.Connect();
}
public ChangeSomeEntity(SomeEntity someEntity, int newValue)
{
//Suppose there's some validation too, non trivial stuff
SomeEntity.Value = newValue;
_engineContext.SaveChanges();
}
}
And report:
public partial class MyReport : Page
{
Engine _engine;
DatabaseEntities _webpageContext;
public MyReport()
{
_engine = new Engine();
_databaseContext = DatabaseEntities.Connect();
}
public void ChangeSomeEntityButton_Clicked(object sender, EventArgs e)
{
SomeEntity someEntity;
//Wrong way:
//Get the entity from the webpage context
someEntity = _webpageContext.SomeEntities.Single(s => s.Id == SomeEntityId);
//Send the entity from _webpageContext to the engine
_engine.ChangeSomeEntity(someEntity, SomeEntityNewValue); // <- oops, conflict of context
//Right(?) way:
//Get the entity from the engine context
someEntity = _engine.GetSomeEntity(SomeEntityId); //undefined above
//Send the entity from the engine's context to the engine
_engine.ChangeSomeEntity(someEntity, SomeEntityNewValue); // <- oops, conflict of context
}
}
Because the webpage has its own context, giving the Engine an entity from a different context will cause an error. I happen to know not to do that, to only give the Engine entities from its own context. But this is a very error-prone design. I see the error of my ways now. I just don't know the right path.
I'm considering:
- Creating the connection in the Engine and passing it off to the webpage. Always instantiate an Engine, make its context accessible from a property, sharing it. Possible problems: other conflicts? Slow? Concurrency issues if I want to expand to AJAX?
- Creating the connection from the webpage and passing it off to the Engine (I believe that's dependency injection?)
- Only talking through ID's. Creates redundancy, not always practical, sounds archaic. But at the same time, I already recuperate stuff from the page as ID's that I need to fetch anyways.
What would be best compromise here for safety, ease-of-use and understanding, stability, and speed?
© Programmers or respective owner