Structuring an MVC application - Model and Data Access [closed] - c#

Closed. This question is opinion-based. It is not currently accepting answers.
Want to improve this question? Update the question so it can be answered with facts and citations by editing this post.
Closed 4 years ago.
Improve this question
I'm rewriting a web app in MVC and I am trying not to get hung up on the architecture, but then, MVC has patters which I want to stick to
My application has views which display data retrieved from a database.
Normally, I would write my controller action as follows
public ActionResult Index()
{
var model = new IndexModel();
model = DbHelper.GetData(); // business layer
return View(model);
}
But I have been doing some reading saying that data access should be done in the model, so is something like this better?
public ActionResult Index()
{
var model = new IndexModel();
return View(model);
}
And IndexModel:
public class IndexModel
{
public string EmailAddress { get; set;}
public IndexModel()
{
// Fetch data in here...
EmailAddress = DbHelper.GetEmail(); // for example
}
}
So, should the controller include the logic to fetch the data, or should the model handle it? A lot of the MSDN examples show the controller populating the model, but that seems to break the layers of MVC

The question is somehow opinion based. But considering the following ideas may help:
Model
Let it be responsible for transferring data between layers.
Use plain classes as View Models or Input Models.
Don't put business logic or data-access into model classes.
View
Let it be responsible for rendering the UI.
Just use Model and don't call business logic classes directly.
Controller
Let it be responsible for handling requests and providing response. Also responsible for controlling flow of application.
Controllers should only call Business Logic methods and they should not contain any business logic
Don't interact with Data Access Layer directly. Let this Business Logic Layet take this responsibility.
Business Logic
Let it be responsible for business operations like changing data, processing data, search and loading data.
Use data access layer methods for CRUD operations. Don't rely on database directly. Let Data Access Layer handle CRUD operations.
Create each business method as a single unit of work which
Data Access
Let it be responsible for CRUD operations with data.
While you can use a ORM instead of this layer, but in a large application, you can also create this layer as layer which uses ORM.
General considerations
Create abstractions for different layers.
Controller should rely on Models and Business Logic Abstractions.
Business Logic should rely on Models and Data Access Layer Abstractions.
Data Access layers should rely on Models and ORM
You can use different model types for different layers or create a shared model library.
You can have a shared library for cross cutting concerns like log.

MVC (Model View Controller) is a broader design pattern governing the ASP.NET MVC applications architecture, but its not the only pattern a given application shall stick to. The ultimate goal is to have neat and clean code, loosely coupled artifacts and focus on code re-usability.
Usually my approach to project architecture is have a separate project for Data-Access Layer(usually a class library project) and another for Business-Layer (to implement business-level decisions) (also a class library project) and an ASP.NET MVC project as a Presentation-Layer project . The Business-Layer project has a dll reference of Data-Access project and Presentation-Layer project (ASP.NET MVC Project) shall have references of both Data-Access and Business-Layer projects.
Now I use dependency injection approach to provide data-access dependencies to controllers in their constructor, something like this
private IDbHelper dbHelper;
public HomeController(IDbHelper _dbHelper)
{
dbHelper=_dbHelper;
}
So the db-access class shall be made available through a dependency injector (Ninject for example) and the individual action methods shall not have to worry about how to create objects. Now your action method shall simply make calls to the dbHelper class like this
public ActionResult Index()
{
return View(dbHelper.GetData());
}
Also please note that besides using Models your application shall need to create View-Models (VMs) (Models returned from database and modified by business layer to meet the business specific needs).
So in short a good project is a combination of several different patterns and architecture styles that are implemented to make the code re-usable, neat and clean and easy for testing.
Thanks.

Consider using dependency injection, especially if you're going to be doing a lot of unit testing (e.g., with Moq). Obaid (user who made a post above) posted good information about this.
See the following reference for more information:
https://learn.microsoft.com/en-us/aspnet/core/fundamentals/dependency-injection?view=aspnetcore-2.2
Note: As shown in the above reference, you will need to configure your services in your Startup class (or whichever type you chose to configure all of your services for MVC).

Related

What to put in Business Logic Layer? [closed]

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 8 years ago.
Improve this question
I have read lots of articles and they seem to vary from one author/developer to the next. In my situation, I am thinking about this setup for testing a project:
Presentation Layer via ASP.NET MVC
Service Layer (my plan is ASP.NET MVC Web API; this is on separate assembly)
Business Logic Layer
DAL using EF
Some articles said I should not put CRUD operations on BLL and BLL should only contain business logic. Also, some said BLL should not access DAL. But what if a business logic needs data stored in DB to calculate/work on logic? I guess my questions would be:
If BLL shouldn't access DAL, how about those business logic that needs data in DB for it to be able to perform the logic?
BLL are entities, right? Are they the same as POCO or would I still have POCO in DAL?
Also, is DBContext in BLL? Some say it should so I'm confused.
What about the no CRUD in BLL? Should I do that?
Repository interface is in DAL?
Any additional comments/suggestions/information on what my planned setup would be very welcome (even if it is not related to BLL).
I worked on a project some time ago.
Our project arquitecture ressembled to what you suggest.
We had an ASP.NET MVC site, which accessed a WEB API (in an external solution).
The WEB API also referenced an external solution entirely made up of static libraries, which contained the data layer (just entities) and the persistence layer.
We also had Data Transfer Objects (MSDN) for communication between the web service and the clients, and to decouple the entities entirely from external solutions.
We had the business logic in the WEB API project. We would create, manipulate and store the entities from within the WEB API HTTP methods.
But we didn't accessed the data and persistence layer directly, we had an intermediate layer, we called it entities manager. These managers would be injected on our WEB API controllers (We used Ninject for Dependency Injection) and would handle the creation of the entity, and also the persistence, so we'd decouple everything.
This approach worked very well for us, and we made a pretty well maintainable and scalable project.
I hope it may be of help for you, and of course, there probably exist better techniques.
PS:
We used an IRepository interface provided to us by the entites manager to persist the entities. This was our only access to the persistence layer. Inner logic, such as persistence strategies (like EF's DbContext, or File IO) would be internal to the persistence project.
This is an example of our bussiness logic in one of our WEB API HTTP methods:
// "repository" is an IRepository<Entity>
entityManager.Transaction( (repository) => {
Entity ourEntity = repository.CreateNew();
//Manipulate the entity somehow
repository.Add(ourEntity);
});
The data will take different forms, for example in the data storage DS (SQL Server for example) they are on relational tables, in the data access layer DAL they are in the Data Model (object model) like Entity Framework EF, in the presentation layer PL they would be in View Model, and on the HTML page or desktop form they will live inside a UI component.
At a single point when a layer calls another layer they have to have a communication channel and a data container that would change the data from one form to another.
Whenever a DAL asks for some data from DS it should be changed from table form to a object model form, so the DAL does not care about the table form. When you send the data back from the DAL to the PL it should be changed to be in a View Model form and again the PL does not care about the object model form, and so on.
You might ask about the BLL layer, I guess this layer most of the time is just a delegate in the middle when there is no logic in the middle, so for some performance matters the PL would access the DAL directly.
I hope this would answer your questions.
EDIT
For the BLL you consider as the mind of the system, the PL is just showing what it receives, and DAL just returned what is asked for to return by acquiring the right DS entities. So the CRUD would be in the DAL.
For Example you need to search for a list of employees, the BLL here is just a delegate layer where it delegates the PL call to the DAL and return back the results. But in case of adding a new employee, the BLL would have an interface with function like AddNewEmoloyee which will do some business logic functions like for example making sure that the salary is according to the employee level range, and then it will call the needed CRUD actions in the DAL.

Where to store methods that relate to the model

I hope this hasn't been answered already, but I don't even know what to search for.
I have an MVC project, and I need to return a list of users from the DB. Simple enough. But I only want to return certain users. Again, simple stuff.
What has me confused is that I don't know where I should put the code for that. If I put it in the controller I end up with the same code in multiple methods, and spread over multiple controllers.
I've currently put the method to return the users in my dbcontext class. That works and seems to make sense, but I wonder if there's a better way to do it? That class would end up getting massive in a bigger project.
I've looked at using repository classes, but that just seems to be adding an additional layer. I'm using EF6, and not doing any unit testing (yet)
The code below shows the structure of my dbcontext class (I've edited out the actual code, to keep it brief).
public class LeadsDB :DbContext
{
public LeadsDB()
: base("Leads")
{
}
public DbSet<User> Users { get; set; }
public IEnumerable<SelectListItem> GetUserList(bool includeBlank = true)
{
return UserList;
}
}
As they say:
All problems in computer science can be solved by another level of indirection... Except for the problem of too many layers of indirection.
So depending on the size and scope of your app, you need to decide how many layers of indirection will let you hit the sweet spot of maintainability for your application.
If your application is going to be really small, go ahead and put those methods on your context directly. If it's going to be big enough for your DbContext to become unmaintainable, I'd create repositories. And so forth.
In the application I'm working on, we only interact with Entity Framework for data-related operations. All of our repositories return DTOs which are abstractions of our data model. Our Controllers further convert most of our DTOs into ViewModels before passing them to the Views. And there's a "Manager" layer between the controllers and the repositories to handle business logic and security-checking. We end up with a lot of layers, but we've found value in decoupling the view, presentation, business, security, and data models.
This looks like an Entity Framework DBContext; if so, then use this as your Data Layer.
Possibly consider using a "Business Layer" abstraction model to do additional things to your objects. Your data access layer should do just that: work with data.
If you have, say, a singleton class as your business layer, then you could use your data layer to directly work with the data, and then the business layer to apply business logic to that data and return it to your presentation layer (be it a website, a windows form, etc.)
The business logic layer could possibly check for the data in cache and if it doesn't exist, then retrieve it from your data layer, put it in cache and return it to your presentation layer.

Decoupling ASP.NET MVC 5 Identity to allow implementing a layered application

I'm new to ASP.NET MVC and I've been developing a MVC 5 application with individual user authentication. I've been doing a layered pattern when doing my applications like separating Model layer, DAL layer, Repos, etc. etc. but now in MVC 5, I want to be able to use the user and role management and authentication which they call Identity, and then still have that layered structure to my application because right now it seems Identity is pretty much coupled with the MVC project itself with the user and role models in there and the context too.
What I did in my application for now is I have all my supposed-to-be-separate layers like my DAL, UnitOfWork, Repos, other models, etc in the MVC project (in separate folders!) just to make it work, for now. And I know it's just not the right way to do it.
So can anyone point me to some good examples or articles about this or explain it directly if it's possible or not and how? Google hasn't been friendly to me about this one. Thanks!
Here is a quick draft of what I'd try...I would create these layers:
Contoso.Core (Class Library)
Contoso.Data (Class Library)
Contoso.Service (Class Library)
Contoso.Web.Framework (Class Library)
Contoso.Web (ASP.NET MVC 5.0)
Contoso.Core:
This layer holds all my entities/classes representing my database TABLES.
So for example, I would have a:
User.cs class.
Product.cs class
ProductDetail.cs class
Etc..
Some people call these entities/classes: the Domain Objects, others call it the POCO classes.
Either or, these entities/classes are defined in the Core Layer since they may (or may not) be used amongst the other layers.
Contoso.Data:
This layer is where I define my ContosoDbContext.cs class. It is inside that file that I have all my DbSet<> defined.
So for example, I would have the following inside my ContosoDbContext.cs:
public DbSet User { get; set; }
public DbSet Product { get; set; }
public DbSet ProductDetail { get; set; }
Needless to say, the Contoso.Data layer WILL HAVE A DEPENDECY on the Contoso.Core layer.
In addition, it is inside that Contoso.Data layer that I would have my Generic Repository and anything related to "data access".
Contoso.Service:
This layer would be where I place all my business rules. For example, I may have a UserService.cs class that could have a Login() method. The Login() method would receive a username/password and call the Repository to lookup the user.
Because the Service layer needs the Repository, I WILL HAVE A DEPENDENCY on the Contoso.Data layer AND because I'll be playing around with the User class (which happens to live inside the Contoso.Core layer), I WILL ALSO HAVE A DEPENDENCY on the Contoso.Core layer.
Contoso.Web.Framework:
This layer would have a dependency on the Contoso.Core, Contoso.Data and Contoso.Service.
I would use this Contoso.Web.Framework layer to configure my Dependency Injection.
Contoso.Web:
The final layer, the MVC 5.0 application, would have a dependency on the Contoso.Web.Framework AND on the Contoso.Service AND on the Contoso.Core layers.
The Controllers, would invoke methods living inside the classes defined in your Contoso.Service layer (for example the Login() method).
The Login() method may or may not, for example, return a User class (null or populated) and because it returns a User class AND BECAUSE we are inside a Controller, our Contoso.Web layer needs a dependency on the Contoso.Service and Contoso.Core.
Of course, I haven't detailed everything here or every layer but this is just to give you an example of the type of architecture I’d use.
So far, I haven't answered your question but with little I know about MVC 5.0 and its new Identity mechanism, I believe the Contoso.Core layer would need to have a dependency on Microsoft.AspNet.Identity.EntityFramework in addition to the Microsoft.AspNet.Identity.Core
Likewise, my ContosoDbContext.cs class would need to implement the IdentityDbContext interface which happens to belong to the Microsoft.AspNet.Identity.EntityFramework.dll.
This means my Contoso.Data layer would have a dependency on Microsoft.AspNet.Identity.EntityFramework and most probably the Microsoft.AspNet.Identity.Core as well...
As you say, when you create a new MVC 5.0 project, all of this exist and is defined within the single application. Nothing is or has been decoupled into layers. So in the above architecture the ContosoDbcontext.cs class lives inside the Contoso.Data layer and NOT directly inside the ASP.NET MVC application.
Since I haven't tried the new ASP.NET Identity nor have I tried to decouple things around, I wouldn't know how to honestly answer your question. I guess you'll have to try and move things around.
If and when you do, feel free to tell us how it went and what are the things/problems you encountered.
Meanwhile, I hope this has helped you shed some light (or not).
Vince

How can I refactor my database access code outside my MVC project but keep my viewmodels inside?

I have an asp.net-mvc website with the following folders:
Controllers
Scripts
Views
ViewModels
Models
DomainModel
I now want to access a lot of this business logic and database access code and data in another .net app (a windows console app so not web at all) so i am refactoring to remove as much stuff as possible outside of the MVC project and into other projects in the solution so that code could be shared with this other solutions.
I have 2 main issues;
My main issue is that I am struggling to find a place to put the code that generates the ViewModel because a lot of this code I would like to reuse in my console app as the console app sends email which requires the same data that is in the view.
Another main issue is that i am struggling to see how i can move my database access code out of the MVC project while still having the ViewModels inside when many of my functions that instantiate my viewmodels start with a bunch of database access code.
Here is a bit of the detail and my process so far:
Step 1 - Move DomainModel into another project - success
So moving the DomainModel project was simple (as that was a lot of raw objects with some business logic on top - nothing web about it).
Step 2 - Thin out controllers - success
I have thinned out as much of my controllers as possible and moved any business logic or complicated data access logic into the Models folder. When i tried to move the models folder outside the MVC project a few things broke:
Step 3 - Attempt to move Models folder outside MVC Project - struggle
In thinning out the controllers, I have a number of different controller actions that go to a model class and return my ViewModel that i pass back into the view. Something like this (in my controller class):
public ActionResult ApplicationDetail(int id)
{
AppDetailViewModel applicationViewModel = Model.GenerateAppDetailViewModel(id);
return View(applicationViewModel);
}
So files in my Model folder are dependency on the ViewModel classes. I do want to centralize the GenerateAppDetailViewModel() function as that is used in multiple different controllers. Also, in my console app (which sends out email, i often want to get all the data that happens to be on some view so my code "wants" to leverage the viewmodel as well .. if i move it out of the MVC project then I can reuse but i think have the dependency issue (clearly i don't need SelectListItem in my console app but in other cases where they are just container objects of different data needed to generate a view I do want to reuse)
or another thing that broke was the dependency on:
System.Web.Mvc
because I have a lot of code that:
queries a table in a database
Converts that into a collection of objects (i am using nhibernate)
Convert that into either some DTO object (which is sitting in ViewModels folder) or a List of SelectListItem objects (to be used to populate dropdowns in the view) which is part of System.web.mvc.
I wanted to look for suggestions on the best way to break out this dependency so i can move as much code out of the MVC project as possible for reuse.
The issue is that if i try to suck my ViewModel code into the Model folder and into another project then again i get stuck because the ViewModel classes have a lot of dependency on
System.Web.Mvc
due to things like SelectListItem.
Should i have 2 view models folders (one in the MVC project that has specific system.web.mvc references and another one that sits in a different project?). It seems like the dependency on SelectListItem is what keeps causing the contention
In most examples that i have seen ViewModels do have a dependency on System.Web.Mvc such as this tutorial
I have seen these questions:
Asp.Net MVC SelectList Refactoring Question?
Where should selectlist logic sit in ASP.NET MVC, view, model or controller?
which are sort of related but not sure they answer my specific overall refactoring question stated.
View models are specific to the particular application. I guess that the view models would differ between your web application and your console application. So have each application define its own view models and the corresponding mapping between the domain models and the view models. Don't have your domain models posses methods that convert them to view models because this way you are completely tying your domain layer to the UI layer which is the worst thing to happen. Use a mapping layer (which will be specific to each application type). AutoMapper is a great example of a mapping layer that you could have.
Don't even try to reuse ASP.NET MVC view models in a console application. As you have already found out they will contain references to System.Web.Mvc because for example a dropDownList in ASP.NET MVC is represented with the IEnumerable<SelectListItem> class whereas in a Console Application, god knows, maybe an IEnumerable<SomeItemViewModel>.
Conclusion: View models and mapping back and forth between the domain and view models belong to the UI layer (a.k.a ASP.NET MVC, Console, WPF, ...).
I understand what you want to achieve, and I must tell you: it's absolutely normal to reuse the same ViewModels for different UI layers. After all, VM is part of MVVM pattern, and that pattern is all about separating concerns. And, separation means the ability to replace lower-level layers with another implementations. That is the purpose of separate software layers (among others).
For the beginning, you must assume that your MVC web project is MVVM-based. That will mentally help you make correct decisions. I guess you already did this since you use ViewModel term.
Make ViewModels become platform independent. It's possible, and it has nothing to do with SelectListItem. After all, SelectListItem simply contains the option text/value pair, plus the flag whether it's selected or not. You obviously can express the same information in a different way. After passing this Generic kind of ViewModel to the MVC, you can convert the generic "SelectListItem" to the MVC SelectListItem. Yes, it is sort of mapping, and it does not matter whether it takes place in the MVC view or before passing it to the View. But it must happen on the UI layer (MVC web project), since it's a platform specific mapping concern.
You mentioned data access code: that's a separate software layer, usually abstractly injected into the ViewModels. I foresee no problems with this part.
Hence, you will end up having different software layers (most likely in different .NET libraries): Data Access Layer, ViewModel layer, MVC Web layer.
There is a possibility of having MVC ViewModels as well (one passed from Controller to View) defined in the MVC project, but those will be simply handling (probably accepting) the generic ViewModels and exposing things in the MVC View-specific terms (mapping, inheritance, your imagination?). And this is normal too - after all, MVC is a web-based UI and it definitely has platform-specific differences that must be handled on the platform level, not before. MVC specific ViewModel would be a good place to handle the mapping from generic to MVC SelectListItem.
Once this refactoring is done, there's nothing stopping you from implementing another UI layer - Console application that you are mentioning, by utilizing the same generic ViewModels as the other UI layer - MVC Web project. When using the generic ViewModels in the console application, if you face the Console platform-specific issues, you can come up with the platform-specific ViewModels in the same way as I explained above for the MVC-specific ViewModels.
You can create viewmodels in controller with extension methods:
Controller:
public ActionResult ApplicationDetail(int id)
{
var model = _serviceLayer.GetSomeModel(id);
var viewModel = model.CreateInstance(model);
return View(viewModel);
}
Create this SomeModelExtensions in your mvc project
public class SomeModelExtensions {
public AppDetailViewModel CreateInstance(this SomeModel model) {
var viewModel = new AppDetailViewModel();
// here you create viewmodel object from model with logic
return viewModel;
}
}
In general I use the following setup/architecture when laying out an MVC app where I may need to reuse the models:
MVC Project: everything web related. I define ViewModels here and map them to the domain models.
Models Project: class library with all your domain logic.
Repository project: This is a class library which access the DB and the Domain Models.
The way it works is that the MVC project will use the (hopefully injected) Repository library to get the Domain Model and map it to its own ViewModel.
If you want to separate the mapping as well, you can put the Mapping Layer, as others have suggested (using AutoMapper eventually), in a separate project. The mapping layer will reference the repositories (and the domain models), while the MVC app will only reference the Mapping layer.
The problem is that the mapping layer, in creating ViewModels, will need a reference to System.Web.Mvc as you found out and you cannot escape this. This is why others have said, and I agree, that you should have a mapping layer per project.
A nice way to get around this is to have a further generic mapping layer with mapping classes defined for the common cases (like the email). Then in the specific child classes you can define the mapping for specific cases (like the ones depending on System.Web.Mvc).
So the end stack would be something like the following, dependencies going down. Of course everything should be interface based.
MVC App Console App
| |
| |
MVC Specific Mapper Console Specific Mapper
\ /
\ /
\ /
GenericMapper <- EmailMapper and EmailViewModel can be implemented here
| |
| |
Repository |
| |
| |
DomainModels
The above is not struggle free and probably the effort of splitting the mapping apart is not worth the candle if there are only one or two common cases. That way, from the Generic Mapper down you are free from the System.Web.Mvc library, while above you are free to forget about DB access code (In a sense the Mapper will act as a Repository for the App).
I assume the MVC web will use the same data as the console app + extra fields, right?
so, what about inheritance your ViewModel from Model? That way you would be able to reuse the model and get custom fields on your ViewModel as needed.
public class AppDetailModel
{
public int ID { get; set; }
public string Name { get; set; }
}
public class AppDetailViewModel : AppDetailModel
{
public string ViewProperty { get; set; }
}

How do you implement a business logic layer when using entity framework as data access layer?

Say i have 3 layers
layer 1: WPF Project (contains: xaml, viewmodels, mvvm framework)
layer 2: business logic layer (contains: plain c# classes)
layer 3: entity framework (contains: repository/data access classes)
when you dont want to expose your DAL(layer 3) to View(layer 1)
how do you implement the business logic layer well?
im having a hard time putting values back and forth the BLL objects and DAL entities.
can you please help?
Entity Framework doesn't work really well in a "disconnected" model. Unless something has changed, I've never been able to get it to work great easily.
You could use AutoMapper in Layer 2 to create ViewModels to present to Layer 1, but then you'd still have to send the changes back to Layer 3, which could be a pain.
If you're only developing a small app that will not change in the foreseeable, then just do whatever is quickest now. If you want a long-term maintainable app, then let me put forth the following.
The problem with this vertical layer approach is that whenever you need something in the view, you will have to add it to both the Business Layer (even if the business layer doesn't care about it), and the Data Layer. This requires your business layer to look like 1) UI views of the data 2) business views of the data and 3) the database representation of the data. That and/or you need a lot of mapping in-between layers. All of which dilutes business layer's actual purpose of representing business logic. What tends to happen then is that all the business logic gets migrated into transaction methods (that could just as well be static methods) to just change states on data objects. There's nothing at all wrong with that if your problem domain is nothing but CRUD with no complex logic. With complex logic, such business methods can get pretty tricky or even have undefined outcomes (because complex interdependencies on "fields" can be contradictory and hard to resolve).
Assuming you have complex logic, user views of data and business representations of data are often very different, and so UI views end up with specialized models of the data. If I were you, I just embrace this and use a simple version of the CQRS principle. That is, have the data for your UI views come from a different place than where your business operations are executed. In your case, I might have an EF Model in your DAL that only services your UI views, and gives them exactly what they need (whether by database views, stored procedures, or pre-compiled report tables). Then create a separate EF model that services only the needs for your Business entities. Then when you are ready to perform an actual business action, the UI's viewmodel action method can load the business object from the business EF model (or better yet, call an object factory from the business layer which does this) and run an appropriate action on the business object. Note that I'm also making the assumption here that your database is highly relational (mostly 2nd and 3rd normal form) and you are set on using EF.
I would not try to make your View Models into business logic. This makes your business logic not easily reusable on other platforms or applications (like web). MVVM should only service the UI. In my mind, the V (view) represents what the user sees and operates. The M (model) represents what the user chose on that view. And the VM (view model) translates between the two. Your program should then take the user's validated choices (UI model) and extract the needed data out of it to perform an appropriate business operation.
Instead of exposing all of your DAL to View Layer, just exchange your domain objects (EF objects) between all layers. The structure may be similar to the following:
Presentation Layer-------- ^
BLL --------------------------- | Data objects
DAL (Repositories etc.)--- |
So, all of your layers will be disconnected; but they will share the same domain objects. In real world, you can implement a similar structure by creating a seperate dll for Entity Framework entities which is shared by all layers. Note that ObjectContext shall be only visible to DAL (by default, entities and object context are generated in the same dll, you need to seperate this into two dlls).
In addition to the answer by Daryal, you can define your business-objects in your BL to be POCO's, and use EF in your DAL layer to read them from or persist them to the database.
If you define an repository-like interface in your BL (or unit-of-work, whatever naming you give it), and implement the interface in your DAL, then all you need is a little DI to get an instance of the repository-class without having to reference the DAL all the time. It works like a charm for me.
See here and here for more information.
Your ViewModels are your application in MVVM, so they should be handling things like data access through your Repository classes, or business logic (either directly, or indirectly using your validation classes).
If you don't want to directly reference the classes, use an Interface but be aware that you'll need to have some way of passing your inherited class to your ViewModel. I once did a project where we had a library of shared interfaces, such IRepository interfaces, and everything was imported/exported using MEF so the layers didn't reference each other directly.
The final (simplified) layout was:
Models -> Contained plain data objects that could do simple validation on their own data (length, min/max values, etc) but that didn't do any advanced validation or business logic. Did not reference any other library.
Common -> Contained interfaces, utilities, and other commonly shared classes. Referenced the Model library only.
DAL -> Contained Data Access and Repositories based on repository interfaces found in Common library. Referenced Common library for interface definitions and utilities, and Model library because it contained the data models used or returned in data access calls
ViewModels -> Contained application and business logic. Referenced Common for its utilities and interfaces, and Models for the data models
Client -> Contained Views. Referenced Models and ViewModels so it could write DataTemplates for both object types
Entity framework is suppouse to be used as "Logic Layer" by itself.
Your idea may have some sense, to use combine technologies.
Howevere, I think some of those Micros. libraries, where designed to be used separately, unless, otherwise explicitly combined & mentioned in their websites.
Good Luck.
I second daryal and I have implemented this in some projects. It is absolutely OK to use POCO as business objects.
Another approach instead of creating 2 projects (one for DB Context and one for Entities) is to use one DAL/DATA project only and reference it in BLL. Then inherit the POCO class in BLL and use that class in UI layer. Below is the basic sample code:
// assume this is EF generated POCO
namespace Owner.Project.Data{
public partial class Product
{
public int ProductId { get; set; }
public string ProductName { get; set; }
}
}
// this is manually created class in BLL
using Owner.Project.Data;
namespace Owner.Product.Business{
public class StoreProduct : Product {
public bool Add (string productName){
// TODO - add product using EF as you normally do
}
}
}
Now you can reference the BLL in your UI project and use StoreProduct class there. To achieve loosely coupled pattern, Of course you could also inherit the StoreProduct class from an IStoreProduct interface and make use of it in UI or web service but that is another topic.

Categories

Resources