Where should I instantiate the Entity Framework's ObjectContext in a 3-tier applicaiton - asp.net

I have a 3-tier web application wit ha bunch of simple forms. One to list records, one to edit a single record, etc. The works.
I have a DataLayer where my EDMX is.
I have an App Layer where my POCOs are.
I haev a BusinessLayer with all my controller classes, etc. (not MVC!)
I have a UI layer where my web UI is.
The EDMX has many, many tables wit ha lot of navigation properties.
Of course, when I fetch the data in one of my controllers, e.g. GetCustomerById(int id), I create the Object context and close it when I'm done.
However, the ObjectContext is out of scope when I try to access the navigation properties in the UI layer.
Should I do (using MyContext = new MyContext()) {... } in the web layer?? that does not seem right.
Should I create another set of POCOs that I populate from the entities' data from the BizLayer?
What happens when I want to save data entered in a web form? Would I call a BizLayer controller e.g. SaveCustomer()?
My question is, how do you design the web UI layer if I want to be able to properly access the navigation properties of an entity?
Note:
EDMX is set to LazyLoading.

You want to use lazy loading in UI but it means that UI defines lifetime of your ObjectContext. There are many ways to achieve this without exposing the context to UI. You can for example use this simple approach:
You mentioned some controller which uses context and disposes it. So make your controller disposable and instead of disposing context in every method use single context for whole lifetime of the controller. Dispose the context in controller's Dispose method.
Instantiate your controller per request. So for example you can create instance of controller in Page.Load and dispose it in Page.Unload.
Use your controller and entities as you want. Whole processing of the request (between Load and Unload) will be in scope of single living context.
Anyway you should not need lazy loading in Web application too much. In your form you usually know exactly what entities you need so you should request them directly with eager loading.

Related

Where to place Logic in MVC with ViewModel Pattern

I am using ViewModel in asp.net mvc 3.
In my case I have a controller which initiate a ViewModel connected to a View.
If no variable DateForLookUp is appended in the URL the controller initialize the ViewModel with DateTime.UctNow, otherwise it use the variable.
I need create to link on the View. When a user click the link I must take the DateForLookUp value and adding or subtract one day.
My question:
Where is appropriate to place this logic, ServiceLayer, the ViewModel, the Controller or the View?
VIEW
#Html.ActionLink("Next Day", "Daily")
#Html.ActionLink("Previous Day", "Daily")
CONTROLLER
public ActionResult Daily(string dateForLookUp)
{
DateTime dateTimeForLookUp;
if (string.IsNullOrWhiteSpace(dateForLookUp))
dateTimeForLookUp = DateTime.UtcNow;
else
dateTimeForLookUp = DateTime.Parse(dateForLookUp);
var eventsInDate = eventAggregateService.FindAllForDate(dateTimeForLookUp);
EventsAggregateDailyListViewModel eventDailyVM = new EventsAggregateDailyListViewModel();
eventDailyVM = new EventsAggregateDailyListViewModelBuilder().Build(eventDailyVM, dateTimeForLookUp);
return View(eventDailyVM);
}
In my opinion (and in practice), I would place any and all logic in the service layer.
I break my MVC apps into several different projects to keep all layers nicely separated:
AppName.Configuration: to handle any configuration of the app (i.e. pulling in web.config/app settings, resource files, etc.)
AppName.Data: this is the data layer where all DB access is performed (no business logic). The DBML/EDMX lives here, my repository class(es) live here as well.
AppName.Models: this is where all of my ViewModels are defined for MVC, as well as other model objects needed throughout the application.
AppName.Services: This is my business layer, everything must pass through here to get to the data layer or to the presentation/web layer. ViewModels are constructed from the database objects, data validation happens here, etc.
AppName.Web: this would be the MVC application.
AppName.Data.Test: Unit tests for Data app
AppName.Services.Test: Unit tests for the services
AppName.Web.Test: Unit tests for the MVC controllers
AppName.Web.UI.Test: Unit tests for the web user interfaces (using WATIN)
I also have a set of classes packaged up into NuGet packages that I can add to my app if/when needed, namely (for this example):
CompanyName.Data: Common library for data layer logic
CompanyName.MVC: Common library for ASP.NET MVC integration
CompanyName.Utilities: Common library for miscellaneous utilities
My controllers do nothing except get the ViewModels from the service layer to send to the views and then receive the data upon post from the views and send it off to the services layer for validation, processing, saving back to the repository, other business logic, etc.

In MVP, how is Data Model complexity dealt with and where to dynamically show/hide controls?

In most of the MVP examples I've seen, the presenter calls some service, which calls some repository, which returns an entity. In most asp.net web applications that I have worked on, the logic is never that simple. In my last project, my presenter called a presenter service layer that had to jump through hoops to get the data that was to be shown on the screen.
Details: The service layer queries a database for, let's say, 8 entity objects, some of which are nested within each other, then the code maps those entities to one huge object base off of an XSD. That xsd object was then passed to a 3rd party library to do something with it. After it returned the processed xsd obj, the code then had to parse through that xsd object, using a middle layer view formatter class to extract and build what I call the "View Model" (I've heard some call it a DTO). This View model was then returned from the service layer to the presenter and then databound to a repeater.
Where does the logic for show/hide controls go? Should that be a member in the DTO or should the presenter derive this value? (I chose to have it as a member in the view model)
Is it ok to have nested ViewModels(DTOs) or should other user controls be used to break down the complexity?
What is a good way to wire up a presenter with all of the Pages/UserControls that use it; meaning one presenter with 5 IViews that require the same instance of the presenter. Should user controls be self contained or should they rely on the "parent" IView(page) to give it the proper presenter?
Instead of having a view model, why not just use the Interface that the Page implements and pass that to the service layer (through the presenter) and let the service hydrate the IView? (Doing this would cause the service layer to have a reference to it, isn't that bad?).
public class ViewModel
{
public bool ShowHeight { get; set; }
//Is there a bettter way to do this?
public List<NestedViewModel> NestedViewModel { get { return _nestedViewModel; } }
}
IMO, the view should manage itself in showing and hiding; it is the view and is responsible for managing the UI behaviour.
I think complexity is OK as long as its not too overbearing; you can break it down into nested subpresenters/views if you need to.
Most MVP frameworks populate the presenter/view relationship from the view, especially since ASP.NET runs in the context of the page (the page is the HTTP handler processing the request, so it's what is alive at that point). The page, during init, goes and establishes the view/presenter relationship. Most examples do it this way. I built an MVP framework and have also established this approach.
You could; that's considered passive view, though the presenter should still do the work, and not directly pass to the service layer.
This is my opinion and there are many ways to do this.

Right place to initialize an object in ASP.NET MVC

I am new to the MVC way of programming so please bear with my basic question !
I have a Status class with a default constructor (in an ASP.NET MVC application).
public Status()
{
this.DatePosted = DateTime.Now;
}
I noticed Fluent NHibernate calls this constructor each time it fetched a list of existing Status objects from the database. Hence, the constructor does not seem like the right place to initialize the date.
Where should I move this initialization ? Moving it to the Controller (Add action of Status controller) also seems to violate the principle that the Controller should not make any business decisions. Should I move it to the Status DAO then ? (In traditional ASP.NET Web Form applications I worked with, a DAO simply accepted a business object and saved it to the database and did not contain any logic)
I would like to know the right way to accomplish this. Is there another layer I am missing here where this initialization should take place?
I noticed Fluent NHibernate calls this
constructor each time it fetched a
list of existing Status objects from
the database. This does not seem right
This is exactly what is supposed to be happening. Why wouldn't an ORM call the default constructor for an object? I think every hand rolled DAL and ORM in the world would trigger DatePosted to be reset because thats just how constructors work.
Your DatePosted property should probably set via ModelBinding or manually in the controller and not be part of a constructor.

Does Prism/Unity have a "service preloader"?

I've got a number of modules in a Prism application which load data that takes 3-8 seconds to get from a service.
I would like to be able to say in my bootstrapper something like this:
PSEUDO-CODE:
Customers allCustomers = Preloader(Models.GetAllCustomers);
And this would run in a background thread and when the user actually needs the variable "allCustomers" it would be fully loaded.
Is there an automatic service in Prism/Unity which does this type of preloading?
No, there is not.
However...
What you can consider is adding your ViewModel with a ContainerControlledLifetime to the container in your ConfigureContainer method that the views can use. You'd kickoff your threaded request in the constructor of your ViewModel and allow Views to pull this ViewModel out of the Container.
Even if they grab the ViewModel out of the container before the GetAllCustomers method is done firing, they will be notified correctly if the property you store the customers in implements INotifyPropertyChanged correctly.
If it was more appropriate, you could also do this from the Modules (in the Initialize method), rather than in the bootstrapper (for instance, if your Module was what actually knew about your Customer's Model).

Calling a getter without assigning it to anything (lazy loading)

I have a DTO which can be fully loaded or lazy loaded using Lazy Load Pattern. How it is loaded depends on what the Flex Application needs. However, this DTO will be sent to a Flex application (swf). Normally, a collection for instance, will only be loaded when called. In my case however, the collection will only be called in Flex, so my implementation on the .NET side will obviously not work in this case (except if Flex would do a server call... something I would like to avoid).
In the getter of the collection, the data is retrieved from the database. If I would be working with ASP.NET pages, it would work, but not if the DTO is sent to Flex.
How would you deal with this? I could call the getter before sending the DTO to Flex, but that seems awful... + calling the getter can only be done if it is assigned to something (and the local variable that will hold the collection will never be used...).
You can introduce a method to load dependents - loadDependencies - that should take of all lazy loading for your DTO object before being sent over the wire (to Flex). You can abstract this method to an interface to streamline such process across different DTOs. There is nothing against using getters the way you described it inside this method.
I would probably introduce a Finalize method for the class and perhaps a FinalizeAll extension method for various collections of the class. This method would simply go through and reference all the getters on the public properties of the class to ensure that they are loaded. You would invoke Finalize (or FinalizeAll) before sending the object(s) to your Flex app. You might even want to make this an interface so that you can test for the need for finalization before transfering your objects and invoke the method based on a test for the interface rather than checking for each class individually.
NOTE: Finalize is just the first name that popped into mind. There may be (probably is) a better name for this.

Resources