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

Related posts about c#

Related posts about design-patterns