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

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

Related

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

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).

How to make the data access technology (Entity Framework) ignorance from the presentation layer (ASP.NET MVC)?

Premise:
I am exercising Domain-Driven Design and I separate my solution into 4 layers:
Presentation Layer
An ASP.NET Web API 2 project for a RESTful API web service
An ASP.NET Web MVC5 project for a documentation and admin screens
Application Layer
A class library project responsible to take commands from presentation layer and consume any domain services
Domain Layer
A class library project that contains business models and logic
A class library project that contains the domain services
Infrastructure Layer
A class library project that contains all the concrete implementation, like dataq persistance using Entity Framework, logging using Log4net, IoC using Simple Injector, etc
The domain layer only has a set of repository interfaces defined for the aggregates and it's up to the implementation data access mechanism which exists in the infrastructure layer to hide the implementation details.
In this exercise, I decide to use Entity Framework Database first approach. And of course, there is a app.config in the infrastructure project that contains a connection string.
Problems:
Ok, I spend a great deal and time trying to separate all the concerns and to focus on domain models. In the presentation layer (i.e., the API and MVC projects), there is no direct reference to the infrastructure project. And IoC container has been setup so all concrete implementation of the required interfaces would be injected into controller constructors.
When I select, for example, the API project as start project and run it, I got
An exception of type 'System.InvalidOperationException' occurred in EntityFramework.dll but was not handled in user code.
Additional information: No connection string named 'xxxxxx' could be found in the application config file.
Question:
Now I understand if I install Entity Framework into the API project, copy and paste connection string from the app.config of the infrastructure project into the web.config of the API project, things will work. But that breaks our original purpose of separating concerns, doesn't it? If we do that, then what's the point of using Domain-Driven Design and making the data access technology ignorance from the presentation layer?
The reason we don't directly reference direct implementation of data access technology (i.e. concrete implementations that use dbContext and Linq) is that we could easily switch the underground access technology to something else.
So what would be the proper way to do it?!!
I do not want to install Entity Framework in my presentation layer, nor copy the connection string everywhere. I want all the data access and concrete implementation of repositories exist in just one library.
The Entity Framework configuration must be in the project where it is being used. This doesn't mean it's going to break your layered structure or your separation of concerns.
Remove all entityframework elements from your app.config. Create your own connection string element and provide it to entityframework on app startup.

Where to put Business Logic classes in an Entity Framework - ASP.NET MVC 4 Solution?

I have a Solution with one project is Entity Framework and have my ASP MVC project, I looking for some advice or opinion about the idea of create in top of my POCO objects and the DBContext, a Business Logic Layer with static classes that have the all the methods (example a ContactBLL class with GetContactByID, GetAllContacts, GetContactsByType) to allow the access to the model data and that can be accessed in the Controllers Actions. In that way I don't have to put the implementation code of this methods in Controller Actions methods, and it can be reusable invoking this methods in other Action Controllers. I will appreciate your opinion because it could guide me to respond a question I've asking to myself around a week based in the answer to this one (about where to define the DBContext and how use it).
You can create different projects according to core functionality.
Data Access Layer(DB context and repository etc.) you can make Project.DataAccess, it will have only db context class and repository.
Business Logic Layer(Project.Business) it will have business logic and make call to data access layer.
UI Layer(Project.WebUi) it is mvc project.
and so on.
for detail info you can see this http://prodinner.codeplex.com/ code
Create separate class library for your POCO,
then create another class library for your repository, this should
include only the interfaces needed for your repository
and the implementation will be on another class lib like Project.EF,
Project.NH which will include Entity Mapping, Migration, Repository
implementations. but in reality, chances are you wont be changing
your ORM lib once it was implemented because it will just cause you
a lot of headache(just my 2cents).
you'll create your business layer(class lib) and
web project as separate lib. Models folder of your MVC project will contain your ViewModels.
this is what Im using right now and of course not the best structure, it just something that Im happy with :). hope it helps.
In general, there are four standard projects in a ASP.NET MVC - Entity Framework solution. They are 1) MVC, 2) Core/Business Logic Layer(BLL), 3) Data Access Layer/DBContext (DAL) and 4) Common/Utility.
Standard MVC project consists three main elements which are Model, View and Controller. However, middle to complex solution usually cuts off the Model element from MVC project and moves it back to BLL, we call it as ViewModel(POCO). Following this structure, MVC project is now responsible for employ/use the services from BLL and control the UI through controller.
Business Logic Layer (BLL) is the core of implementing business logic. It is responsible for serving request from the MVC project and work with DAL to persist data. As said above, BLL is the place to define ViewModel, its relations as well interface/ abstract class to support implementing design pattern. Viewmodel(POCO) is likely mapping one-one to data entity at DAL but we do not use the data entity directly on View. Following this structure will help to increase the customization on ViewModel like adding constrains
DAL is the place for DBContext and its data entities.
Common project consist of shared functions like Logging which is used in 1) 2) and 3)
Please read more at
https://www.codeproject.com/Articles/70061/Architecture-Guide-ASP-NET-MVC-Framework-N-tier-En
https://chsakell.com/2015/02/15/asp-net-mvc-solution-architecture-best-practices/

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