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.
Related
Sorry for my English, I am writing a real estate appraisal module and decided to try writing in the DDD paradigm.
I looked at examples and different articles and formed the following picture for myself (simplified):
ApplicationCore.Domain - the core of business logic, contains all the necessary objects divided into 2 typesа
Entitys - if an entity needs to be stored in a database and it is a ready-made complete business logic object.
ValueObjects - all other properties that encapsulate the behavior, are compared by the value of the fields, and are part of Entity
It is very important to create only valid objects, so I create everything through factories with a validator, and the constructors are private.
There should be no references to other dependencies, as isolated as possible.
ApplicationCore.App - a layer above ApplicationCore.Domain, contains a link to it.
works with objects from ApplicationCore.Domain and uses external services through Port/Adapter.
Port - For example, an abstraction of a repository, its implementation through an Adapter on the Infrastructure layer.
interaction logic for ApplicationCore is in AppServices - for classic implementation or in Command / Request - for CQRS
Infrastructure - contains a link to ApplicationCore.Domain and ApplicationCore.App.
Implements the ports of the ApplicationCore.App layer
Entities are independent from each other and refer to each other by keys for interaction.
I kept the basic logic of the assessment system in this paradigm.
But here it was necessary to add a service that receives additional information for evaluation from different sources, while in wiretapping mode.
Those. Works against the background of listening to TcpIp socket
Service settings are stored in the database and change frequently - i.e. you need to introduce a new Entity
A chain is formed
DataProvider (ApplicationCore.Domain) -> IDataProviderRepository (ApplicationCore.App) -> EfDataProviderRepository (Infrastructure).
DataProvider - must depend on ITcpIpTransport, without it it is just a set of settings for TcpIpTransport.
Logically, DataProvider is a service for receiving data, but it has settings and state stored in the database, i.e. you need to make it Entity.
If you make the DataProvider dependent on the Infrastructure layer, then ApplicationCore.Domain will also have ports to external services, is this permissible?
how best to implement it.
I've to admit that is a bit hard to understand everything. Especially at the end, you speak about object that isn't clear where they are and what they do.
Anyway, you cannot use anything for the layer above (infrastructure) into the layers below (application and domain). I don't know how would you do it, but as a simple dependency it would not leave you compile any project. You'll end with a circular dependency.
Given that you would not do this, you can build a service (I do it with static functions to avoid any kind of unwanted implementation) into the domain layer. That service use interfaces that are implemented into the application layer. Into the application layer you'll also use (or reuse) interfaces that will be implemented into the infrastructure layer.
I'm a C# coder with a (Windows) sysadmin background. I've been looking at the various service frameworks in order to create a unified REST-API for various infrastructure components (windows management, hardware management, etc.). I've settled on using ServiceStack as my framework for this, but have a question on how to manage my DTOs. Most of the time my source data is from non-database objects, which include:
Other web services (usually SOAP based). I usually bring these in via "Add Web Reference" (most, but not all, are asmx).
.NET Objects (usually WMI/WinRM/PowerShell [System.Management], or Active Directory [System.DirectoryServices])...
In some unfortunate cases, raw text output I get as a result of invoking a command (via ssh or cmd).
In all of these cases, I will have to call some sort of Save() method to update properties. In addition, there might be some non-CRUD methods I would like to expose to the REST service. Usually I don't need everything from the source data (for example, in the case of web service data, I'm only interested in boxing up certain properties and methods of a particular proxy class). My understanding is that my DTOs should be clean and not have any dependencies. Since I don't believe I have an ORM I can use, what design pattern should I use to map my data to a DTO?
Apologies if I'm misusing any terminology here...
With a variety of backend services and data sources, I think it would be hard to use anything highly structured like a framework to map your data to DTOs. I would keep it simple:
Keep your DTO classes separate from any of your backend classes. Generally resist the temptation to try to reuse code, use inheritance, etc., in your DTOs (though sometimes I find it useful to declare interfaces for the DTOs to implement). This will keep the interface of your your ServiceStack service clean and independent of backend details.
There are some extension methods available in ServiceStack to easily map properties between two classes: TranslateTo, PopulateWith, PopulateWithNonDefaultValues, etc. The link above mentions these. The trick is that while your DTO classes should not be subclasses of, or directly reusing your backend classes, you will find it convenient to have the property names match up if you want to use these mapping methods.
Keep your ServiceStack service classes simple; their primary responsibility should be translating between DTO classes and lower level model classes, and making one or two method calls on business logic classes to do the actual work.
It sounds like it would be useful for the highest level of your business layer--the classes that your ServiceStack services interact with--to present a clean interface that abstracts away the details about the source and format of a given type of data. So you may want three layers of model classes. From top to bottom: DTOs, business layer POCO classes, and framework-specific classes for specific backend services like web reference generated code or whatever.
I think that's about all there is to it.
I recommend that you define DTOs that meet the requirements of your API, and then have a 'business logic' layer that mediates between the actual objects and your DTOs.
Your ServiceStack services will have a dependency on both the DTO definitions and the business logic layer, and the business logic layer will have a dependency on the DTO definitions and the real-world object definitions. In effect, your REST services and DTOs will act as a facade over the real-world APIs.
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.
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.
I have a project structure like so :-
CentralRepository.BL
CentralRepository.BO
CentralRepository.DataAccess
CentralRepository.Tests
CentralRepository.Webservices
and there is an awful lot of dependencies between these. I want to leverage unity to reduce the dependencies, so im going to create interfaces for my classes. My question is in which project should the interfaces reside in. My thoughts are they should be in the BO layer. Can someone give me some guidance on this please
On a combinatorial level, you have three options:
Define interfaces in a separate library
Define interfaces together with their consumers
Define interfaces together with their implementers
However, the last option is a really bad idea because it tightly couples the interface to the implementer (or the other way around). Since the whole point of introducing an interface in the first place is to reduce coupling, nothing is gained by doing that.
Defining the interface together with the consumer is often sufficient, and personally I only take the extra step of defining the interface in a separate library when disparate consumers are in play (which is mostly tend to happen if you're shipping a public API).
BO is essentially your domain objects, or at least that is my assumption. In general, unless you are using a pattern like ActiveRecord, they are state objects only. An interface, on the other hand, specifies behavior. Not a good concept, from many "best practices", to mix the behavior and state. Now I will likely ramble a bit, but I think the background may help.
Now, to the question of where interfaces should exist. There are a couple of choices.
Stick the interfaces in the library they belong to.
Create a separate contract library
The simpler is to stick them in the same library, but then your mocks rely on the library, as well as your tests. Not a huge deal, but it has a slight odor to it.
My normal method is to set up projects like this:
{company}.{program/project}.{concern (optional)}.{area}.{subarea (optional)}
The first two to three bits of the name are covered in yours by the word "CentralRepository". In my case it would be MyCompany.CentralRepository or MyCompany.MyProgram.CentralRepository, but naming convention is not the core part of this post.
The "area" portions are the thrust of this post, and I generally use the following.
Set up a domain object library (your BO): CentralRepository.Domain.Models
Set up a domain exception library: CentralRepository.Domain.Exceptions
All/most other projects reference the above two, as they represent the state in the application. Certainly ALL business libraries use these objects. The persistance library(s) may have a different model and I may have a view model on the experience library(s).
Set up the core library next: CentralRepository.Core (may have subareas?). this is where the business logic lays (the actual applciation, as persistence and experience changes should not affect core functionality).
Set up a test library for core: CentralRepository.Core.Test.Unit.VS (I have Unit.VS to show these are unit tests, not integration tests with a unit test library, and I am using VS to indicate MSTest - others will have different naming).
Create tests and then set up business functionality. As need, set up interfaces. Example
Need data from a DAL, so an interface and mock are set up for data to use for Core tests. The name here would be something like CentralRepository.Persist.Contracts (may also use a subarea, if there are multiple types of persistence).
The core concept here is "Core as Application" rather than n-tier (they are compatible, but thinking of business logic only, as a paradigm, keeps you loosely coupled with persistence and experience).
Now, back to your question. The way I set up interfaces is based on the location of the "interfaced" classes. So, I would likely have:
CentralRepository.Core.Contracts
CentralRepository.Experience.Service.Contracts
CentralRepository.Persist.Service.Contracts
CentralRepository.Persist.Data.Contracts
I am still working with this, but the core concept is my IoC and testing should both be considered and I should be able to isolate testing, which is better achieved if I can isolate the contracts (interfaces). Logical separation is fine (single library), but I don't generally head that way due to having at least a couple of green developers who find it difficult to see logical separation without physical separation. Your mileage may vary. :-0
Hope this rambling helps in some way.
I would suggest keeping interfaces wherever their implementers are in the majority of cases, if you're talking assemblies.
Personally, when I'm using a layered approach, I tend to give each layer its own assembly and give it a reference to the layer below it. In each layer, most of the public things are interfaces. So, I in the data access layer, I might have ICustomerDao and IOrderDao as public interfaces. I'll also have public Dao factories in the DAO assembly. I'll then have specific implementations marked as internal -- CustomerDaoMySqlImpl or CustomerDaoXmlImpl that implement the public interface. The public factory then provides implementations to users (i.e. the domain layer) without the users knowing exactly which implementation they're getting -- they provide information to the factory, and the factory turns around and hands them a ICustomerDao that they use.
The reason I mention all this is to lay the foundation for understanding what interfaces are really supposed to be -- contracts between the servicer and client of an API. As such, from a dependency standpoint, you want to define the contract generally where the servicer is. If you define it elsewhere, you're potentially not really managing your dependencies with interfaces and instead just introducing a non-useful layer of indirection.
So anyway, I'd say think of your interfaces as what they are -- a contract to your clients as to what you're going to provide, while keeping private the details of how you're going to provide it. That's probably a good heuristic that will make it more intuitive where to put the interfaces.