I have an MVC solution setup like this, with three 'projects'.
Web (MVC Project, Views, Controllers, ViewModels)
Models (Domain Objects)
Persistence (nHibernate Mapping, SessionFactory)
I need to begin building the repositories, and was going to start with the Authentication Model. Basically following the default MVC template, have an IMembershipService and an IFormsAuthenticationService and related classes (using custom code, not built in authentication providers).
My question is ...where should this go? My Repositories will need access to both my Domain objects and my Persistence Layer. However I keep reading that any kind of 'coupling' means it is a bad design. So I am hesitant to create a fourth project for the Repositories/Services that references the Models/Persistence ...but I can't really find any other way to do it logically.
This is very subjective.
Do what makes sense to you and your team.
I throw them in with the rest of my Repositories. I mean a User is pretty central to any application right? Does a User own anything? If so then isn't he an root?
Repositories are part of the domain.
Tension will always exist between reducing assembly references and minimizing number of projects. That is, you can make each assembly reference fewer dependencies by breaking up functionality into more fine-grained assemblies; however, excessive division of a project into many assemblies requires more effort to manage.
Another point worth mentioning is that authentication has a couple sides to it. One is managing the model around Users, Roles, Permissions, etc. - this is a domain concern. The other is interfacing with the context of execution (whether this is an ASP.Net app, WinForms, etc.) - this is an infrastructure concern. Consequently, I end up with a small service in my MVC project or WinForms project that performs functions like setting Forms Authentication cookies, or setting the current thread principal, etc.
The Separated interface pattern says that your models and repository interfaces should be in a seperate assembly, apart from the GUI and the actual repository implementation. This is to be able to switch implementations later on and to be able to simplify testing.
I would have no problem with putting the interfaces along with the repository interfaces and the actual implementation in the mvc project or the repository project. It's quite easy to move stuff later on if you use a IoC container.
Related
I am currently setting up a simple MVC application that is structured as an Onion Architecture. For simplicity's sake, assume that I have the following projects (disregarding the business and database layers, at the moment):
Sample.Web - This is the ASP.NET MVC Application
Sample.Application - This contains the application services.
Sample.Infrastructure - This contains the infrastructure services.
For now, I am using Ninject (although that will likely change). So, with Ninject MVC, I am registering the Application and Infrastructure services at startup, using the Sample.Web to act as the composition root. Application services from Sample.Application are injected into the controllers, and that is straightforward enough and working well.
Where I am having issues, though, is determining how to properly initialize MassTransit, in the equation. Ideally, I want to have a generic interface to wrap the ConsumeContext instance and allow for me to set up the events. I do not seem to be able to fully set up the instance from within Sample.Infrastructure, as the infrastructure does not/should not know what the events are. I would assume that the consumer classes should exist in Sample.Application, and I do not think that the infrastructure should have a dependency on knowing the consumers.
On startup, System.Web will load the NinjectModule from each System.Application and System.Infrastructure. Does that mean that System.Web should have explicit knowledge of the consumer classes, so that it can configure the IBusControl instance, or is there a more elegant solution?
Right now, the path that I think I am going down is that Sample.Web will load the NinjectModule instances, as it does, and then I will configure the ConsumeContext from Application_Start, after I have explicitly loaded the consumers. However, that would mean that I would have to rebuild/redeploy Sample.Web if I ever add consumers, which is less than ideal and is the root of my concerns. Assuming that consumers are defined within Sample.Application, and all event publications and subscriptions exist within Sample.Application, having to touch either Sample.Web or Sample.Infrastructure to add a consumer is code smell.
Many thanks, in advance.
Edit
As always, after hitting submit, something else comes to mind. I think that one possible solution may be to have Sample.Web as Sample.Application for the known endpoints. Since all events will be published and subscribed from Sample.Application, it would make some sense to have Sample.Web create the actual instance in Sample.Infrastructure and compose the endpoints from what it learns from Sample.Application.
Am definitely open to other solutions, though.
I am about to start developing a medium sized ASP.Net MVC application.
I am trying to get the design right. I intend to have the following layers:
UI layer (MVC)
Service Layer
Repository Layer
Data Access Layer
I will be using Unity as my IOC container and EF4.1 Code First for Data Access.
The app will be split into several assemblies. I have a problem deciding which assemblies I will need
and where to put the following:
Entities/Domain objects e.g. Customer, Invoice
DTOs e.g. CustomerDTO, InvoiceDTO
Service interfaces e.g. ICustomerService
Repository Interfaces e.g. ICustomerRepository
Services(Service interface implementation classes) e.g. CustomerService
Repositories (Repository Service implementation classes) e.g. CustomerRepository
ViewModels e.g. CustomerViewModel
Enums
My question is:
How do you usually split yours and why?
Edit: prompted by the #TheHurt's answer.
How would the references be between the assemblies, i.e. which assembly would be referencing which?
This is how I might tackle it:
App.UI assembly:
ViewModels go in Models area.
App.Repository assembly:
Abstract implementation of concrete repository.
ICustomerRepository
App.Repository.SQL:
Concrete implementation.
EFCF POCOs
App.Services assembly:
Abstract service.
ICustomerService
DTOs
App.Services.Implementation:
Concrete service.
CustomerService
App.Common:
Shared code.
Enums
There are a couple issues that I still struggle with. You lose the data annotations from EFCF when you cross the services boundary. So then you have to do server side validation or you have to keep your view models validation in sync with the repository entities. It feels that the more layered things are, the more DRY is violated. I suppose that is par for the course though when your view models don't map to your entities directly. You could have your view models be your DTOs and toss them into the Common assembly, but that seems to couple things too tightly if you have the need to be super flexible with your services.
EDIT
If you are wanting to integrate WCF into the mix you would probably want to create data contracts that are very close to the MVC view model (or use the contracts as the view model). You probably wouldn't expose that to the world as the service would be specific to that implementation of your MVC site, spin up another service for public consumption. If you are doing a WCF service you probably want to have all of your business logic in the service, the controllers would just handle navigation logic.
Side note, I try to stay away from the "metal" as much as possible, while developing a design that will allow me to separate the code into various layers in the future. If I cannot clearly explain the various system layers to my manager with one sheet of paper, the design is more than likely too complex. Everything for the most part will look pretty in Visio if it is designed well.
As far as how things reference each other: UI would ref the Serivce (or service implementation, which may not be needed. Just keep it all in the same place.). Service refs the Repository. The repository implementation refs nothing, since it is loaded by IOC. Everything refs Common.
I've been working with S#arp Architecture but this can probably be applied to any DDD architecture (Domain / Core, Application Services, Infrastructure, and Presentation).
There are many ASP.NET MVC examples that show the controller operating on the domain model through repository interfaces. In fact, the S#arp Architecture tutorial has the StaffMembersController referencing IStaffMemberRepository where it calls FindAllMatching (implemented in the repository). The StaffMember entity, also in the domain/core layer, looks like a data bag with properties and minimal validation on the properties.
Let's say you have a controller that is getting bloated with things that look like business concerns. After reading Microsoft's "Designing Business Entities" chapter in Microsoft's Application Architecture Guide, I believe these concerns could be called "Domain Services".
I want to put these domain services in the domain/core layer but I'm not sure where they should go. Should I create a services folder in the domain/core project that hosts interfaces with an implementations folder underneath it? That seems like a good approach, but I want to see how others have handled this.
Thanks!
What you're calling Domain Services in your question are what I would call Application Services. This kind of confusion over the three different types of service (application, domain and infrastructure) is what lead to the term "Tasks" being used in Who Can Help Me? (instead of application services).
Broadly speaking, I see domain services as actions/behaviours within the domain that don't belong to any single entity - this is pretty much as described in the Evans DDD book. Application services are more of an orchestration layer/facade over the domain that allows an application to interact with the domain without needing to know the full detail about how it works.
So I believe you need an application services layer to remove the bloat from your controllers. This is the approach that's shown in WCHM and it's the one I now follow in my apps.
In terms of where they should live - I'd send to say you should have them in their own project. If you're being purist about it, the contracts should also live in their own assembly, which means that if you like, you can remove all knowledge of the domain from your controllers. However, the WCHM approach places the contracts in the Domain project, and allows the controllers to have knowledge of the entities. Some people complain about this but it's basically just a compromise.
Hope this helps
Jon
Personally, I'm not a fan of how S#arp Architecture (at least, in their demo projects) has the controllers talk directly to the repositories. My $0.02 is that the domain services should be the interface between controllers and repositories. The repositories exist strictly to abstract away the database (e.g., so that you can replace it with, say, LINQ to Objects during testing). The domain services implement your business logic. You want to be able to test those without connecting to a database, or having to mock out your entire session.
An example that I think gets this right is the MVC project developed in Mark Seeman's book, Dependency Injection in .NET.
We built a real world ecommorce platform based on Sharp Architecture and created a demo project that showcases the architecture we put in place. This added the ViewModels, Mappers & a Task layer which helps separate concerns. This is going to form the core architecture of Sharp Architecture v2.0
See http://whocanhelpme.codeplex.com/ for more details.
When I start work on a new web application I tend to reach for the same tried & tested architecture of ASP.NET MVC, BLL (consisting of a set of services that contain all business logic) and a DAL (consisting of a set of repositories that facilitate the unit of work pattern over something like EF/*Linq to SQL*).
The controllers talk only to services, the services only to repositories and other services. At the service layer are where models are defined and these are used as input/output to/from the controllers.
My question is: what are others doing? I'm interested in knowing if people are doing anything different in the context of an ASP.NET MVC web application. For instance, there are concepts like CQRS and Domain Events. Is anyone using these to solve a problem with the method I've described above?
This question is mainly a source of attempting to discover what I don't know I don't know. I hope it's not too vague, but I think it's important to see what others are doing to evaluate your own methods.
We're basically doing what you're doing, except that we consider our repository interfaces to be services (they are defined in the business layer), and therefore our controllers often access them directly. An IoC container takes care of injecting the correct repository implementation via constructor injection. So the data layer depends on the business layer, and is in charge of implementing the repositories, while the business layer just assumes that all the repositories it has defined will be available at runtime.
We've further divided our product up into different modules of functionality. Some of the modules depend on one another (for example, everything depends on our core functionality, and most of the other modules depend on the web portal module), but keeping them in separate dlls helps us to avoid making these modules be too tightly coupled. The system can therefore only load the DLLs for the modules that a given client has paid for. We plan to use an event bus with events defined in the core module to allow the modules to communicate via a publish/subscribe model.
I am using CQRS with MVC. Its nice. You still use the MVC pattern, but in the controller I use the command pattern for the write, and just pure NHibernate Linq for the read... also some SolrNet for the read. :-)
I am a Java Developer making the transition to the C# world. I've gotten a pretty good handle on ASP.NET MVC (and can compare/contrast it to the concepts I learned for Struts).
However, I'm looking for advice on how to structure my project. Currently, I have two solutions in the project: the MVC Web Application and a ClassLibrary section.
The application uses a tiered architecture: Controllers/Services/DAOs. To make things work "right", I have the Controller and Model classes in the MVC solution, and Services, DAO, and Security in the ClassLibrary solution. Unfortunately, this is causing all sorts of minor issues (example: extending the UserAccount object from the Entity Framework on the ClassLibrary side is ambiguous when I try to extend it on the MVC side for form validation).
The only solution I can come up with is to put EVERYTHING into the MVC project, and organizen what is currently in the ClassLibrary under the App_Code folder. It would solve some issues, but just seems "wrong" to me; my Java projects separated code into a src directory and views (jsp's) into ta webapp directory.
What do some of the more experienced .NET developers think?
Generally in .NET solutions, the best bet is to separate code into different projects only if that code may be useful to other applications, or when the code itself represents a complete solution to some problem domain. A class library that is only referenced by one application project is a waste.
Also, keep in mind that .NET does not allow circular references between objects in two different assemblies (which translates one-to-one with projects usually).
In your example I would suggest that you consider one class library for the model, services, and security... depending on what you mean when you say "services" though.
In most cases, data access is somewhat coupled to the concept of the MVC model, so you might consider putting the data access in there too... but if you have a very cleanly separated data access layer it might fit into it's own class library.
The controllers and views generally should go into the web project directly.
In general, my advice is to split stuff into separate projects ONLY when you have an actual "need" to do so. But assemblies and projects are NOT a good way to represent layers or tiers in most applications. Those are logical concepts that don't always map well to a physical project structure.
If you design your actual classes well and avoid tight coupling, you can usually move code into class libraries later if a real compelling need does arise.
What do you mean by making things work "right"? I find that most issues can be fixed by simply including the namespace in the web.config's namespace import section. When you do that, your models from the other assembly are automatically resolved and they show up in the MVC dialogs, and in intellisense when coding views.