I want to create application with layered architecture. I have separate
Model project with only model classes
Data project responsible for CodeFirst configuration, migrations, etc.,
Service project responsible for business logic, and preserving the data in the database using EF
Dto project with classes used between Web app and service
Web project with asp.net mvc application.
My goal was to separate these projects so that Web project knows nothing about Model and Data - it just consumes Service using Dto classes, so the Web project should just reference Service and Dto. Everything was great until I configured Asp.Net Identity - in order to configure authorization I had to reference Data and Model project which I had wanted to avoid. Is it possible to achieve my goal, and (if so) how to do it.
My second question is: is my desing ok from the separation of concerns point of view?
I might separate all the ASP.NET Identity things into its own project housing both the EF data access and identity models. Think of it as separating the concerns more topically or by the subject matter, rather than by function.
So your web app would then reference Service, Dto, and Identity- and everybody seems to have their own corner of the world.
The goal, imo, is not necessarily to divvy up code by similar functionality, but to eliminate dependencies where none are needed, and to hide (or rather protect) domain knowledge into isolated and authoritative blocks.
Yes, your design is basically solid and generally works well.
Related
I'm creating application with layered architecture. I have separate
+ 'DataModel' project with only model classes
+ 'BusinessLogic' project that containing my business
+ 'Core' project for run Business from ui
+ 'ViewModel' project
+ 'Web' project with asp.net core application.
My goal was to separate these projects so that Web project knows nothing about DataModel so the Web project should just reference Core and ViewModel. Everything was great until I configured Asp.Net Identity - in order to configure authorization I had to reference DataModel project which I had wanted to avoid. Is it possible to achieve my goal, and (if so) how to do it.
Note:
I'm using this how to separate model library when using asp.net identity for writing my question and i don't find accepted answer as my answer!
When you create a website that uses Identity directly, you must provide it with various Identity "stores": UserStore<TUser>, RoleStore<TRole>, etc. The default and easiest approach is to use Entity Framework Core as the backing for the store(s), and Identity comes with built-in stores to work with EF Core. However, using that requires access to the context, which means you then will need a dependency on your data layer. There is no way around that when using AddEntityFrameworkStores<TContext>.
If you want to keep your data layer abstracted, then you will need to either 1) use a centralized identity provider, such as IdentityServer or 2) create custom stores.
IdentityServer, for example, supports using both EF and Identity as a backing. That does mean it will need a dependency on your data layer, but IdentityServer would be exist in a separate project. Your actual website would handle auth via IdentityServer endpoints, and therefore would have no dependency on your data layer. In fact, it doesn't even know or care that you're using Identity at all at that point.
Creating custom stores will be a bit more difficult, obviously, and unless you provide an true abstraction layer, you'll still ultimately end up with a dependency on your data layer. That might be something like a microservice(s), where the store will actually make HTTP requests to the service to get the objects it needs, instead of making database queries directly. The microservices, then, will hold the data dependency.
One thing you might not be considering in this is that the dependency is there even without a direct reference. For example, if your Core project uses stuff from your DataModel project, and then your Web project uses stuff from your Core project, your web project has an implicit dependency on your DataModel project. If you look at the bin folder after building, for example, you're see a DLL for your DataModel project and even one for EF Core there, despite not explictly using either one in your Web project. In this case, using separate projects helps only to division the logic in perhaps a more succinct and understandable way, but it does not serve to actually abstract any dependencies.
I am currently working on an intranet website that uses Active Directory and SQL Server 2008. I have chosen ASP.NET's MVC design pattern and am now trying to figure out how to get a proper architecture for my project concerning the Data Access part using Entity Framework. I have been struggling for days in order not to go in the wrong direction (knowing that I'm the only developer in my company, it's my first experience and nobody knows about recent Frameworks). I have read about architecture and how to do it right, but I am not sure I grasped everything correctly (How do architect an ASP.Net MVC app with EF?).
Here is what I was thinking of doing, each layer having their own project (pardon my drawing skills):
Controller(MVC Project) ---uses---> Service Layer (Project) ---uses--> EFDal (Project)
^ | ^ |
| | | |
|<-------<-----returns ViewModel |<---------<------returns Query Result
EFDal is EntityFramework Data Access Layer.
And from what I understood, Service layer would contain methods that call the DAL which in turn is used to access data.
Do you see something wrong in my approach?
Am I right in saying the Service Layer, is the one containing all operations? (eg: Searching a user in DB -> Service Layer launches search by calling EFDal which returns the value, and in turn Service Layer returns a ViewModel to the controller)
(also see: Creating a Service Layer for my MVC application?)
Finally, Should my Service layer classes implement Interfaces for persistence purposes?
As a student we only used MVC pattern for our projects, and never had to expand the solution with new projects because we worked on small projects. Here I feel like misconceiving the architecture will end up in disastrous maintainability. Thanks for your help!
You're almost in the right direction. However, the ViewModel in this case should reside in the application layer, i.e. your MVC layer. The service layer should in turn return a data transfer object, more commonly known as the DTO.
Think of the ViewModel as a simple POCO class that is built for the View, it can be a collection of various DTO returned by various services from your service layer.
Benefits of DTO
You are not directly exposing your domain entities, i.e your EntityFramework POCO classes. However, a case can be made for a project small enough to avoid DTO all together.
In case in the future you decided to add an WebAPI function along your MVC project, say, for an iPhone application. The new application uses the WebAPI that also consumes the service layer, most of the service layer codes can be re-used since they return DTO classes and not ViewModel that is constructed for the View itself.
For your Data Access layer, no one explains better than this guy. Entity FrameWork With Repository Pattern
As for project structure, I would suggest an onion architecture. Onion Architecture. If you can understand this article well enough, you should be all set.
We've got a solution with multiple MVC web projects and now adding a client-facing WebApi project.
The API will be a much more scaled-down version of what is available through any of the web projects (though it will likely expand much more over time), so we've come to a decision-making point for how to handle the Models.
What are the best practices for handling Models across different projects?
It's my understanding that a Model in a WebApi project will, for example, use certain property attributes which are meaningless to an MVC web application. And also as an example, the Display attribute is meaningless to the WebApi, but very useful in a View.
This leads me to believe I should be creating a separate set of Models for the WebApi, but also wondering if I'm missing something.
I understand that this could be a question that may lead to a range of opinions, so I'm mostly looking for what are considered industry best practices.
In my solution where i have Web API and MVC web app, I have the below structure
Models : My Entity/Business objects. These are created by Entity framework from my database. These are almost same as my db structure. My Repositary methods (for data access) returns either a single instance /collection of instances of this classes. My data access project is a separate class library which has been referred in other places like my web api project etc..
Web API ViewModels : The Viewmodels (POCO class) specific to the Web API interfaces/action methods.
MVC Web app ViewModels : The Viewmodels (POCO class) specific to my razor views. I had even inherited few of these from the Web API Viewmodels and added additional properties as needed.
I use a separate project for the DTOs, so that the projects that need to consume them do not get into issues with circular references.
I would have the WebApi project map your models into the DTOs. If your MVC project is consuming the WebAPI output, it just needs a reference to the DTO project. This keeps you from having to refer to the WebAPI project directly.
I have the following situation: I have to create a website and a web service that will share a part of the functionalities.
This is why I do not want to write code twice.
I have thought of the following architecture:
MyApp.BusinessLogic --> here we save the DataModels to the database
MyApp.DataAccess -> DataModels & Entity & mapping
MyApp.UI.Models -> ViewModels
MyApp.UI.ServiceLayer -> Acceses the Business Logic, creates the UI ViewModels for the website, and transforms the ViewModels back into DataModels for saving with the help of the BusinessLogic Layer
MyApp.WebSite
MyApp.WS.Models - >Ws Models, these will be the objects passed between the client and the WS
MyApp.WS.ServiceLayer -> Accesses the business Logic, creates the WS Models for the web service, and transfoms the WS.Models back into DataModels for saving with the help of the BusinessLogic Layer
MyApp.WebService
Is the architecture overkill ? What problems will I encounter ? Will I have problems with the controllers in the ASP.NET MVC website ?
When I design my applications I do it like this. My only issue is the dull copying of models to view models. The best way to overcome this to use AutoMapper.
I would though create some unittests because there is a high risk of breaking the app when changing the services (and visa versa). Unit testing would tell you that early on.
Define basically :)
If you want to reduce the code usage, why not create your service, then just consume it in the app?
So if you would have something like...
Foo.DataAccess
-Foo.BusinessLogic
--Foo.ServiceLayer
Then have that referenced by:
Foo.WebService (including models for view/update... but probably simplify externally)
Then use
Foo.WebApp
and have this consuming Foo.Webservice to make the data calls on it's behalf
Having UI and web service models increases your code duplication, you could use something like Fluent validation to let the service handle your validation, and enhance the basic validation system.
I am an experienced developer but I am new to web application development. Now I am in charge of developing a new web application and I could really use some input from experienced web developers out there.
I'd like to understand exactly what experienced web developers do in the code-behind pages. At first I thought it was best to have a rule that all the database access and business logic should be performed in classes external to the code-behind pages. My thought was that only logic necessary for the web form would be performed in the code-behind. I still think that all the business logic should be performed in other classes but I'm beginning to think it would be alright if the code-behind had access to the database to query it directly rather than having to call other classes to receive a dataset or collection back.
Any input would be appreciated.
If you go strictly with asp.net (and don't use MVC models), then you are on the right track considering N-tier development and separation.
Your code-behind should be related to presentation/UI, and should rely on middle tier layers for business logic etc.
In general the easiest way to split up the app, is to have multiple projects in a VS solution, such as:
ASP.NET Web application project (Presentation/UI)
C# class library - Business Logic Layer
C# class library - Data Layer
Database (SQL or otherwise)
You can of course have many other libraries and layers as needed, but essentially the n-tier approach that works in non-web environments applies well using the same principles here.