I am trying to wrap my head around IoC containers. As I delve deeper into this design pattern I come across multitudes of abstraction layers, interfaces and concrete classes when before I was simply instantiating a data-context class, using it and then disposing of it.
Whilst I am keen to continue forward there are some outstanding issues I don't know how to resolve and would like some clarification and guidance.
In a generic web application with 2 projects (mvc web & data layer
containing e.f.), if our dependancy resolver expects a repository
that implements a specific interface (allowing us to switch
repositories at any time in the future), where is this interface
defined? I dont see how it can be defined in the mvc web project because then the data access layer will become dependant on it and it cannot reside in the data access layer as then the mvc project depends on the dal and i've missed the whole point of this excercise. So is
the answer to define it in both projects and have each project
reference its own copy? ..Is that even possible? Or do i need to
create a third service layer project and stick one interface
declaration in it and have both projects reference this?
Ive seen a number of articles talking about Unity IoC with
interfaces such as IProductRepository, IClientRepository and
IProductService, IClientService (this is what I was referring to in
my opening paragraph). Am I correct in assuming that each of these
instances is supposed to reference a table in my database? If so
what happens if i have 50 tables? do i need to create 50 repository
interfaces and 50 table related interfaces just to decouple everything?
And how does using EF with POCO classes impact things? do i need to
have each POCO implement its own specified interface?
thanks
Ideally you would split your solution into several projects.
You would have a contracts project where your interfaces are defined, a dal where a concrete version of those interfaces are implemented.
Your mvc project would then reference the contracts project to handle the references to the types.
You would use an IOC container to scan the assemblies in the bin folder and find a concrete implementation of the dependencies for your controller. This means that you would build your dal into the bin folder of your mvc project. This means you can switch the dal out for other implementations simply by placing a new dll in the bin folder.
As for the repositories and tables, I tend to group them by business function. So a business function of managing users and their related tables would be in a user repository etc. but that is down to personal preference imo.
When you are breaking your project into tiers you are correct in not wanting your data layer to rely on a project further up the stack. In general you want these dependencies to be unidirectional. You can either continue what you are doing and put the interfaces in the data layer, or you can create a new project to house the model code, including the repository and service interfaces. Your data layer would depend on the model code, and your mvc layer will depend on the data layer.
To address your second question I would say this is where the art of design comes in. You don't necessarily want a one to one mapping between your entities and your data tables. If it makes sense and you believe it's manageable, especially with the help of Entity Framework, then go ahead with the one to one mapping. But keep in mind that the responsibilities of the persistence layer and the domain model layer are different. If the persistence layer starts to bog down your work creating the domain model then it's time to put some work into separating the two.
More important are the interface 'facades' that are going to be exposed to the mvc project. These are going to require some degree of decoupling from the model and persistence layers. They should be distilled down to the core responsibilities of the model. You don't want to clutter your application layer with the intricacies of your domain model.
Related
We would like to create a new project with a clean architecture. So our team decided to have:
Repository pattern
Data Access Layer
Business Access Layer
Common Layer (Abstractions such as IPersonRepository, IPersonService, ICSVExport)
Some Core services such as create CSV files.
UnitTests
Now what we have is:
PersonsApp.Solution
--PersonsApp.WebUI
-- Controllers (PersonController)
--PersonApp.Persistence
--Core folder
-IGenericRepository.cs (Abstraction)
-IUnitOfWork.cs (Abstraction)
--Infrastructure folder
-DbDactory.cs (Implementation)
-Disposable.cs (Implementation)
-IDbFactory.cs (Abstraction)
-RepositoryBase.cs (Abstraction)
--Models folder
- Here we DbContext, EF models (Implementation)
--Repositories
- PersonRepository.cs (Implementation)
--PersonApp.Service
--Core folder
-IPersonService.cs (Abstraction)
-ICSVService.cs (Abstraction)
--Business
-PersonService.cs (Abstraction)
--System
-CSVService.cs (Abstraction)
--PersonApp.Test
In my view, our structure is a little bit messy.
The first problem is:
PersonApp.Service has abstractions(interfaces) and implementations
in one class library.
The second problem is:
PersonApp.Persistence has abstractions(RepositoryBase) and
implementations in one class library. But if I move RepositoryBase,
IGenericRepository, IUnitOfWork in a class library called
PersonApp.Abstractions, then I will circular reference errors
between PersonApp.Abstractions and PersonApp.Persistence
What is the best way to organize our solution?
This is probably not a good S.O. question given it's asking something that is opinion-based. When planning out project structure I aim to keep things simple. If an abstraction is for polymorphism I will consider moving interfaces into a separate "common" assembly. For example if I want to provide several possible implementations of a thing, I will have a common assembly that declares the interface, then separate assemblies for the specific implementations. In most cases I use interfaces as contracts so that I can substitute the real with mocks. In these cases I keep the interfaces nested beneath the concrete implementation. I use a VS add-in called NestIn to provide nesting support. This keeps the project structure nice and compact. However, a caveat, if you are using .Net Standard libraries, file nesting doesn't appear to be supported. (Hopefully this changes / has changed)
So for a SomeService, my folder project structure would look like:
Services [folder]
SomeService.cs [concrete]
SomeService.dependencies.cs [partial] [nested]
ISomeService [nested]
the .dependencies.cs file is a partial class where I put all dependencies and the constructor. This keeps them tucked out of the way while I'm working on implementation. I used to rely on #regions way back, but frankly I cannot stand them now. Partial classes are much better IMO.
My repositories live alongside my entities in a Domain assembly.
Entities [folder]
Configuration [folder]
OrderConfiguration.cs
Order.cs
Repositories [folder]
OrderManagementRepository.cs
OrderManagementRepository.dependencies.cs
IOrderManagementRepository.cs
MySystemDbContext.cs
I don't use Generic repositories, rather repositories are designed to pair up with Controllers or Services that they serve. I might have some general purpose repositories that service more than one consumer. (stuff like lookups, etc.) This pattern evolved for me from wanting to satisfy SRP. The biggest issue with things like generic repositories is that they need to serve multiple masters. While an OrderRepository might serve a single responsibility in being worried solely about Orders, the problem I see is that many different places will need access to Order information. This means different criteria, and wanting different amounts of data. So instead, if I have an OrderManagementService that deals with orders, order lines, etc. and touches on Products and other bits and bobs in the process of placing orders, I will use an OrderManagementRepository to serve virtually all data needed by the service, and manage the wrapping of supported operations for managing an order. This means my service only typically needs 1 repository dependency (rather than an OrderRepository, ProductRepository, etc. etc. etc.) and my OrderManagemmentRepository has only 1 reason to change. (But that's getting off topic. :)
I started relying on Nesting a while ago back when you needed ReSharper or the like to get access to "Go to Implementation" for interfaces. Go to Definition would take you to the interfaces, which when in a separate namespace or assembly made navigating around dependencies a pain. By nesting interfaces under their concrete implementations, it's a quick click through from the interface to it's concrete implementation and back. I make use of tracking the current code file in the solution manager so as I navigate through code my project view highlights/expands to the currently viewed file.
Ultimately, your project structure should reflect how you prefer to navigate through the code to make it as intuitive and easy to get around to find the bits you need. That will be different for different people, so partial classes and nesting works really well for me, as I am a very visual person that uses the project view a lot. It might not serve any benefit for people that are hotkey navigation wizards. Ultimately though I'd say keep it simple, and adaptable. Trying to plan it out too much in the early stages is like premature optimization. Don't be afraid to move things around as a project grows. A project that grows simply by adding code will invariably turn into a unstable, confusing tangled mess, no matter how well you try to plan ahead. Good code comes from constant re-factoring which is moving things around and deleting as well as adding. When your style is adaptable and you are building in a way that is constantly refining and code is getting better through natural selection, the structure is free to evolve.
Hopefully that might give some food for thought. Good luck in the green fields!
Edit: Regarding polymorphic interfaces vs. contract interfaces. With polymorphic interfaces where I want to have multiple, substitute-able concrete implementations, this is a case where the interface (and any applicable base class) would reside in a separate assembly. The nesting solution applies for cases where the only substitution is for mocking purposes. (unit testing) A recent example of a polymorphic instance was when I needed to replace an in-built SMS service wrapper to support a new SMS provider. This resulted in re-factoring a hard-coded concrete class from the original code into a SMSCore assembly containing the ISMSProvider interface and some general common definitions, then two assemblies for the implementations: SMSByMessageMedia and SMSBySoprano.
Other cases that come up might be around customizations. For instance I have a number of personal libraries and such for general purpose code, and when implementing them for a client there might be some client-specific "isms" that I want to make. These cases are typically resolved by extending the general purpose implementation (Open-Closed Principle) by overriding, or implementing a provided interface for the custom dependency that the general purpose code can consume. In both of these cases, the client project is going to have a reference to the concrete implementation(s) anyways, so having extendable classes and dependency interfaces in that assembly/namespace doesn't pose any issues. This saves needing to add several different namespaces & assembly references.
I recently have read about the domain driven design. Finally, I came across the structure that my project should have. The structure would be like :
MyApp.Domain which contains entities and repositories interfaces.
MyApp.Domain.Services contains services.
MyApp.Infrastructure
MyApp.Persistence Contains the repositories implementation
MyApp.Application contains viewmodels and services
MyApp.Site
Right now, I just need to reference the MyApp.Domain and MyApp.Application to my site. On the other hand, if I want to use Unity as Ioc. The question is, Should I make reference to MyApp.Domain.Services and MyApp.Persistence as well? in order to register types?
Thanks
How else would Your "Application" know about Your business objects,
if You don't tell it, which assembly they're registered in ?
If You're looking for a more 'Plug-in' based approach, then it's a different story..
If speaking about plugins (not sure how Unity does that)
but the only way I got this to work (withing reasonable amount of effort)
was unit Autofac modules
You'd still need to have a place where You register your assemblies
and have something like a 'Filesystem watcher' that monitors a pat for new .dll's and loads them ect..
A common architecture when practicing DDD is the Onion Architecture. Mostly because it has several improvements over a typical n-tier architecture with barely any downsides.
It allows your domain and domain model to be at the heart of the software. The domain services layer would usually have a dependency on the persistence layer. In an Onion Architecture, this is flipped and the persistence layer holds the references to the domain services/model. To access the persistence layer, the interfaces for the key classes in the persistence layer are held in the domain layer and IoC is used to wire up the instantiation.
First of all, why have you created six different projects? They are just a fictionary separation. If you are the only developer, do you not trust yourself? If you are more than one developer, are your communication so bad that you can't agree on in which direction dependencies go?
Good separation comes from communication and talk within a team, and not because you have created multiple projects (adding a reference is really easy).
If you want to make sure that the code keeps good quality, introduce code reviews, measure the quality with the built in analytic tools or simply write unit tests.
Therefore, project references are not the problem and never have been. Add the reference in a way that makes it easy to run and maintain the application.
If you are serious about DDD forget about the project structure. It doesn't really matter that much. Understand the methodology and what's important in DDD. Buy the blue book by Eric Evans.
I'm creating my first .net/c# website using Entity Framework as my data access layer. I've split my project into layers so that I have DataAccess, BusinessLogic, a separate BusinessObjects layer and the website itself is the UI (Pages/UserControls/Appcode folder). There is also an additional Utilities plugin project.
The EF model has gone in DA, whilst the entity creation has gone into BO. All feels good, but I'm having trouble what logic class belongs in AppCode (UI) and what belongs in BusinessLogic.
Are there any guidelines that can help me determine which side of the line things go?
App_Code is just a handy convenience for you to run code. I would advise you to avoid using that folder. Just create class library projects for all your classes, which would comprise your business logic layer. In the web project, only put pages and controls (ASCX and ASPX files). It makes the logical separation clearer.
There is a reference implementation from Microsoft Spain; which employs EF, Unity, WCF etc. But, note that this implementation may be overengineered for your needs. Before implementation, instead of copying the same structure, it is better for you to decide, which parts, concepts, patterns are useful for you and which are not.
Microsoft N Layer Reference Implementation
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 4 years ago.
Improve this question
I've received the go-ahead to start building the foundation for a new architecture for our code base at my company. The impetus for this initiative is the fact that:
Our code base is over ten years old and is finally breaking at the seams as we try to scale.
The top "layers", if you want to call them such, are a mess of classic ASP and .NET.
Our database is filled with a bunch of unholy stored procs which contain thousands of lines of business logic and validation.
Prior developers created "clever" solutions that are non-extensible, non-reusable, and exhibit very obvious anti-patterns; these need to be deprecated in short order.
I've been referencing the MS Patterns and Practices Architecture Guide quite heavily as I work toward an initial design, but I still have some lingering questions before I commit to anything. Before I get into the questions, here is what I have so far for the architecture:
(High-level)
(Business and Data layers in depth)
The diagrams basically show how I intend to break apart each layer into multiple assemblies. So in this candidate architecture, we'd have eleven assemblies, not including the top-most layers.
Here's the breakdown, with a description of each assembly:
Company.Project.Common.OperationalManagement : Contains components which implement exception handling policies, logging, performance counters, configuration, and tracing.
Company.Project.Common.Security : Contains components which perform authentication, authorization, and validation.
Company.Project.Common.Communication : Contains components which may be used to communicate with other services and applications (basically a bunch of reusable WCF clients).
Company.Project.Business.Interfaces : Contains the interfaces and abstract classes which are used to interact with the business layer from high-level layers.
Company.Project.Business.Workflows : Contains components and logic related to the creation and maintenance of business workflows.
Company.Project.Business.Components : Contains components which encapsulate business rules and validation.
Company.Project.Business.Entities : Contains data objects that are representative of business entities at a high-level. Some of these may be unique, some may be composites formed from more granular data entities from the data layer.
Company.Project.Data.Interfaces : Contains the interfaces and abstract classes which are used to interact with the data access layer in a repository style.
Company.Project.Data.ServiceGateways : Contains service clients and components which are used to call out to and fetch data from external systems.
Company.Project.Data.Components : Contains components which are used to communicate with a database.
Company.Project.Data.Entities : Contains much more granular entities which represent business data at a low level, suitable for persisting to a database or other data source in a transactional manner.
My intent is that this should be a strict-layered design (a layer may only communicate with the layer directly below it) and the modular break-down of the layers should promote high cohesion and loose coupling. But I still have some concerns. Here are my questions, which I feel are objective enough that they are suitable here on SO...
Are my naming conventions for each module and its respective assembly following standard conventions, or is there a different way I should be going about this?
Is it beneficial to break apart the business and data layers into multiple assemblies?
Is it beneficial to have the interfaces and abstract classes for each layer in their own assemblies?
MOST IMPORTANTLY - Is it beneficial to have an "Entities" assembly for both the business and data layers? My concern here is that if you include the classes that will be generated by LINQ to SQL inside the data access components, then a given entity will be represented in three different places in the code base. Obviously tools like AutoMapper may be able to help, but I'm still not 100%. The reason that I have them broken apart like this is to A - Enforce a strict-layered architecture and B - Promote a looser coupling between layers and minimize breakage when changes to the business domain behind each entity occur. However, I'd like to get some guidance from people who are much more seasoned in architecture than I am.
If you could answer my questions or point me in the right direction I'd be most grateful. Thanks.
EDIT:
Wanted to include some additional details that seem to be more pertinent after reading Baboon's answer. The database tables are also an unholy mess and are quasi-relational, at best. However, I'm not allowed to fully rearchitect the database and do a data clean-up: the furthest down to the core I can go is to create new stored procs and start deprecating the old ones. That's why I'm leaning toward having entities defined explicitly in the data layer--to try to use the classes generated by LINQ to SQL (or any other ORM) as data entities just doesn't seem feasible.
I would disagree with this standard layered architecture in favor of a onion architecture.
According to that, I can give a try at your questions:
1. Are my naming conventions for each module and its respective assembly following standard conventions, or is there a different way I
should be going about this?
Yes, I would agree that it is not a bad convention, and pretty much standard.
2. Is it beneficial to break apart the business and data layers into multiple assemblies?
Yes, but I rather have one assembly called Domain (usually Core.Domain) and other one called Data (Core.Data). Domain assembly contains all the entities (as per domain-driven-design) along with repository interfaces, services, factories etc... Data assembly references the Domain and implements concrete repositories, with an ORM.
3. Is it beneficial to have the interfaces and abstract classes for each layer in their own assemblies?
Depending on various reasons. In the answer to the previous question, I've mentioned separating interfaces for repositories into the Domain, and concrete repositories in Data assembly. This gives you clean Domain without any "pollution" from any specific data or any other technology. Generally, I base my code by thinking on a TDD-oriented level, extracting all dependencies from classes making them more usable, following the SRP principle, and thinking what can go wrong when other people on the team use the architecture :) For example, one big advantage of separating into assemblies is that you control your references and clearly state "no data-access code in domain!".
4. Is it beneficial to have an "Entities" assembly for both the business and data layers?
I would disagree, and say no. You should have your core entities, and map them to the database through an ORM. If you have complex presentation logic, you can have something like ViewModel objects, which are basically entities dumbed down just with data suited for representation in the UI. If you have something like a network in-between, you can have special DTO objects as well, to minimize network calls. But, I think having data and separate business entities just complicates the matter.
One thing as well to add here, if you are starting a new architecture, and you are talking about an application that already exists for 10 years, you should consider better ORM tools from LINQ-to-SQL, either Entity Framework or NHibernate (I opt for NHibernate in my opinion).
I would also add that answering to as many question as there are in one application architecture is hard, so try posting your questions separately and more specifically. For each of the parts of architecture (UI, service layers, domain, security and other cross-concerns) you could have multiple-page discussions. Also, remember not to over-architecture your solutions, and with that complicating things even more then needed!
I actually just started the same thing, so hopefully this will help or at least generate more comments and even help for myself :)
1. Are my naming conventions for each module and its respective assembly following standard conventions, or is there a different way I should be going about this?
According to MSDN Names of Namespaces, this seems to be ok. They lay it out as:
<Company>.(<Product>|<Technology>)[.<Feature>][.<Subnamespace>]
For example, Microsoft.WindowsMobile.DirectX.
2.Is it beneficial to break apart the business and data layers into multiple assemblies?
I definitely think its beneficial to break apart the business and data layers into multiple assemblies. However, in my solution, I've create just two assemblies (DataLayer and BusinessLayer). The other details like Interfaces, Workflows, etc I would create directories for under each assembly. I dont think you need to split them up at that level.
3.Is it beneficial to have the interfaces and abstract classes for each layer in their own assemblies?
Kind of goes along with the above comments.
4.Is it beneficial to have an "Entities" assembly for both the business and data layers?
Yes. I would say that your data entities might not map directly to what your business model will be. When storing the data to a database or other medium, you might need to change things around to have it play nice. The entities that you expose to your service layer should be useable for the UI. The entities you use for you Data Access Layer should be useable for you storage medium. AutoMapper is definitely your friend and can help with mapping as you mentioned. So this is how it shapes up:
(source: microsoft.com)
1) The naming is absolutely fine, just as SwDevMan81 stated.
2) Absolutely, If WCF gets outdated in a few years, you'll only have to change your DAL.
3) The rule of thumb is to ask yourself this simple question: "Can I think of a case where I will make smart use of this?".
When talking about your WCF contracts, yes, definitely put those in a separate assembly: it is key to a good WCF design (I'll go into more details).
When talking about an interface defined in AssemblyA, and is implemented in AssemblyB, then the properties/methods described in those interfaces are used in AssemblyC, you are fine as long as every class defined in AssemblyB is used in C through an interface. Otherwise, you'll have to reference both A, and B: you lose.
4) The only reason I can think of to actually move around 3 times the same looking object, is bad design: the database relations were poorly crafted, and thus you have to tweak the objects that come out to have something you can work with.
If you redo the architecture, you can have another assembly, used in pretty much every project, called "Entities" that holds the data objects. By every project i meant WCF as well.
On a side note, I would add that the WCF service should be split into 3 assemblies: the ServiceContracts, the Service itself, and the Entities we talked about. I had a good video on that last point, but it's at work, i'll link it tomorow!
HTH,
bab.
EDIT: here is the video.
So, I have an application structured with the following layers:
As of now, I am not using any concept of Objects to get data from the bottom-most layer. I am simply using DataTables to get data out. I am not happy with this because it requires the Business Logic Layer to be aware of column names, etc.
In my Business Logic layer I have objects that are loaded from those DataTables and the service layer works with those objects via Collections of those objects.
Here's my question. If I wanted to have the Data Abstraction Layer accept and reply with Objects, how do I avoid referencing the DAL from the Service Layer? I've read that object factories are one way and also I've read I could build object transformation functions and so on.
What is the best way you've successfully employed this? My ultimate goal is to provide pluggable DALs for different Database server vendors.
A standard approach, and one I take often, is to have a common library of object models representing my domain: Customer, Order, OrderLine, etc, that are shared across all layers.
Better still, don't share the types across layers, just share the interfaces and have a factory available when instances are required.
You can then have a pluggable DAL, but your DAL still needs to conform to the contract of returning an ICustomer.
This doesn't stop references from being required, a reference to at least the interfaces are needed - as someone else has commented, other references, for the strong types or factories, could then be factored out - such as with IoC/DI frameworks.
The way I see it: a commom model is a cross-cutting concern in your application design, and shouldn't be seen as breaking the layering.
Update: this is a very vague explanation of the solution, so I stand to have it built upon.
Update 2: and now of course to answer your question. A standard way to remove a reference to a DLL directly is to expose the contract via an interface, in your case a DAL method GetCustomers, your Service Layer talks to the interface, but requests a DAL instance via a Dependency Injection / Inversion of Control framework, or more easily, a factory. I usually go the factory route for small apps, it involves another DLL. Service Layer will reference interfaces and factory, DAL will reference interface, factory will reference interface and DAL.
Define simple objects (or interfaces) in a "Common" assembly, and use those.
For this to work, all layers / assemblies that need to exchange data will need to reference this common assembly; because of that you'll want to make the common assembly very very lean in terms of it's dependencies - otherwise you'll pollute the rest of your app.
For a simple application, I like to...
Use an ORM within my DAL to simplify data access (Entity Framework)
Use the repository pattern for CRUD operations (Repository Pattern)
Use the repository pattern as an abstraction of the DAL, mapping ORM's object to DTOs or model/domain objects (DTO)
Also I...
Use a Dependency Injection framework for repositories, this allows you to plug any database (StructureMap)
Write unit tests and mock my repositories (NUnit)
However, if I had a new project, I would go code-first with EF4 instead of having a ORM-DTO mapping layer. (Code-First wit EF4)
Peace!
Another approach is to use plain-old-clr-objects (POCO). Your data abstraction and business layer can leverage this. Under the POCO domain model, typically you'd use a tool like nhibernate to manage persistance.
Rather than interfaces, nhibernate introduces a "proxy" to introduce persistence behaviour invisibly, through decoration (XML file or Attributes) . You can get quite productive with this approach once you get used to it.
Further, all three layers can leverage the same simple POCO objects which can simplify things somewhat.
re: different assemblies, either put the objects in a shareable assembly, or (like MS often do), use code generation to generate the same POCO "schema" in other layers. Sometimes an intermediate assembly is just not shareable... or you'd like to introduce variations in the additional layers (perhaps due to security concerns). So the link is to just depend on serialization, yet at the same time define once (the POCO schema) and introduce the schema to different layers through tooling (the code generation part).
Hope that helps.