Where to place Logic in MVC with ViewModel Pattern - asp.net

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.

Related

Entity Framework 4.1 and Business Logic Layer

I am trying to use Entity Framework 4.0 for an asp .net application. As of now, it will be old style code behind files and without unit testing but in the future I may use MVP and unit testing but as of now, it is not a concern for me. I am using Database First approach. Here is a model ( I could not post image as I need reputation to post image)
Table: Application (ApplicationID, Name, Hidden)
Table: User (UserID, ApplicationID, Username, IsActive)
Table: Role (RoleID, ApplicationID, Name)
Table: UserRole (UserRoleID, RoleID, UserID)
I have been reading a lot about Entity Framework and how to use it but still could not get a very basic idea about some stuff. Where do I write a code like this for Application, User, Role, UserRole etc?
public List<Application> GetAllUnhiddenApplications()
{
List<Application> applist = null;
using (CustomAppsPortalEntities ctx = new CustomAppsPortalEntities())
{
applist = (from app in ctx.Applications
where app.Hidden == false
orderby app.Name
select app).ToList();
}
return applist;
}
I have separated Context and Entities in separate projects Project.Data and Project.Entities respectively. My question is if above code belongs to BLL (class name ApplicationBLL) or DLL (ApplicationDLL)? From past 2 days, I have been searching lots of SO questions, blogs, tutorials and different people have different approach. Here is my dilemma.
If I put the code in Data layer, then in the business layer, I have to create a "pass through" function like ApplicationBLL.GetAllUnhiddenApplications which will return ApplidationDLL.GetAllUnhiddenApplications. I have to repeat it for all the queries and basically whole BLL will eventually become "pass through" layer for DLL. Can you give me a concrete example of what Business layer will be used for in reference to above schema?
If I put the code in Business layer, then linq will exist in Business layer which eventually will be converted to SQL by Entity Framework so it is like exposing query logic to Business Layer.
Our Environment
Our environment is fast paced and want to complete this project as soon as possible with the moderately proper approach where there is a separate layer but in the future when we find time, we may refactor the code and make it really robust but it is not a concern as of now but if the time permits, we want to implement best practices right now versus refactoring code in the future.
The above code would typically be in the BL layer. Using linq in your BL layer is fine because your linq queries are still data persistence ignorant. From linq queries perspective, it's querying objects from entity framework.
What you might be missing is a "repository pattern" and "unit of work patter". The repository pattern acts as an interface to entity framework. It allows you to interact with EF objects like in-memory collections. Typically I keep all repositories in one project and reference accordingly. To give you an example, Microsoft Spain provides a n-tierd example,
http://microsoftnlayerapp.codeplex.com/
It's very over engineered, but I believe it will give you what your looking for.
Many people argue that EF IS the DLL.
Typically, I set my projects up something like this...
D ---> Presentation Layers (MVC, WCF, WinForms, etc)
A |
T V
A ---> Business Logic Layer
|
M V
O ---> Entity Layer / DLL
D
E
L
The Data Models project is really just a collection of POCO's that can be used in any of the other projects.
The Entity Layer is your EDMX file and Context.
It should be fine to access the context in the Entity/DLL layer, since .Net has abstracted everything out for you.
If you think about it, the whole reason to abstract out a DLL layer is so that you can change databases without having to change the BLL. With EF, you can change a database in 1 step and everything should still work.... as long as your schema stays the same.

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

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.

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.

Applying Unity in dynamic menu

I was going through Unity 2.0 to check if it has an effective use in our new application. My application is a Windows Forms application and uses a traditional bar menu (at the top), currently.
My UIs (Windows Forms) more or less support Dependency Injection pattern since they all work with a class (Presentation Model Class) supplied to them via the constructor. The form then binds to the properties of the supplied P Model class and calls methods on the P Model class to perform its duties. Pretty simple and straightforward.
How P Model reacts to the UI actions and responds to them by co-ordinating with the Domain Class (Business Logic/Model) is irrelevant here and thus not mentioned.
The object creation sequence to show up one UI from menu then goes like this -
Create Business Model instance
Create Presentation Model instance with Business Model instance passed to P Model constructor.
Create UI instance with Presentation Model instance passed to UI constructor.
My present solution:
To show an UI in the method above from my menu I would have to refer all assemblies (Business, PModel, UI) from my Menu class. Considering I have split the modules into a number of physical assemblies, that would be a dificult task to add references to about 60 different assemblies. Also the approach is not very scalable since I would certainly need to release more modules and with this approach I would have to change the source code every time I release a new module.
So primarily to avoid the reference of so many assemblies from my Menu class (assembly) I did as below -
Stored all the dependency described above in a database table (SQL Server), e.g.
ModuleShortCode | BModelAssembly | BModelFullTypeName | PModelAssembly | PModelFullTypeName | UIAssembly | UIFullTypeName
Now used a static class named "Launcher" with a method "Launch" as below -
Launcher.Launch("Discount");
Launcher.Launch("Customers");
The Launcher internally uses data from the dependency table and uses Activator.CreateInstance() to create each of the objects and uses the instance as constructor parameter to the next object being created, till the UI is built. The UI is then shown as a modal dialog. The code inside Launcher is somewhat like -
Form frm = ResolveForm("Discount");
frm.ShowDialog();`
The ResolveForm does the trick of building the chain of objects.
Can Unity help me here?
Now when I did that I did not have enough information on Unity and now that I have studied Unity I think I have been doing more or less the same thing. So I tried to replace my code with Unity.
However, as soon as I started I hit a block. If I try to resolve UI forms in my Menu as
Form customers = myUnityContainer.Resolve<Customers>();
or
Form customers = myUnityContainer.Resolve(typeof(Customers));
Then either way, I need to refer to my UI assembly from my Menu assembly since the target Type "Customers" need to be known for Unity to resolve it. So I am back to same place since I would have to refer all UI assemblies from the Menu assembly. I understand that with Unity I would have to refer fewer assemblies (only UI assemblies) but those references are needed which defeats my objectives below -
Create the chain of objects dynamically without any assembly reference from Menu assembly. This is to avoid Menu source code changing every time I release a new module. My Menu also is built dynamically from a table.
Be able to supply new modules just by supplying the new assemblies and inserting the new Dependency row in the table by a database patch.
At this stage, I have a feeling that I have to do it the way I was doing, i.e. Activator.CreateInstance() to fulfil all my objectives. I need to verify whether the community thinks the same way as me or have a better suggestion to solve the problem.
The post is really long and I sincerely thank you if you come til this point. Waiting for your valuable suggestions.
Rajarshi
As I can see from this code
Form customers = myUnityContainer.Resolve<Customers>();
all your code need to know about the customer - is that it's a Form class. So if you use xml configuration for unity you can do the following:
<type type="Form" mapTo="Customer" name="Customer">
</type>
And then you'll be able to resolve it like this:
Form customers = myUnityContainer.Resolve<Form>("Customer");
and there is no need to refference your UI assembly. Offcourse it should be presented in the bin directory or GAC. In this case if you'll develop new Assembly - all you need is to change config and put in in bin or gac.
If you want to make unity configuration from db then you'll have to add referrence to your ui, becouse you'll have to call Register("Customer").

Resources