Solution setup:
DAL (class library)
BLL (class library)
Common (class library (some common functionality - enums, logging, exceptions,...))
Application1 (Windows Application)
Application2 (Windows Application)
WebApp (Web application)
...
Let's say I have a Customer entity, which is:
a table in SQL server
a CustomerDataTable in DAL
a Customer class in BLL
a BLL.Customer class in all the applications
What kind of objects should BLL and DAL use for communication - DataTable or List<Customer> (for example)? In first case, BLL logic should transform Customer object to DataTable and send it to DAL. In secod case, DAL layer should be aware of Customer class, which is in BLL layer. But originaly DLL references DAL and not opposite...
Should I put all classes into seperate assembly, which is referenced by all others (Common, BusinessObjects, ...)? In this case I could use Customer class in all my projects.
Should I even bother to seperate DAL and BLL when I know, that only one BLL will use my DAL. In this case I could merge them together into one project.
PS - I am reading about DataTables and a lot of people say that we shouldn't use them at all. What are better options? Maybe it is time for me to learn some ORM mapping tools :)
In my opinion you should have another Layer (seperate dll). Like "domain", where would you keep all entities like Customer.
Then simply include in all higher levels(DAL, BLL, UI and others) in hierarchy this assembly.
Sample architecture can look like this:
(Database) <-> DAL <-> BL <-> UI
and on all levels you will have access to "domain" layer.
DAL should return List not a DataTable. On some stage your development process you may want to use in DAL some OMR like NHibernate with would also return a List, probably.
it's hard to answer this general question without knowing the application domain well enough.
I would start with thinking about where future changes are most likely and try to figure out from that where flexibility is required.
my following thought are just a suggestion. feel free to consider them and change/ignore what you feel is irrelevant.
separating the DAL from the BLL is almost always a good idea. the data scheme is one thing that should be encapsulated and hidden from the rest of the application, so leave your DataTables, DataSets, ORMs or any other solution hidden in the DAL. the BLL (and layers above it) should use simple data types (meaning simple classes). I think it would be a good idea to put those classes in a Model class library that has no references and can be used everywhere.
it feels like you have a bit too much layering...do you really need a Customer class in the BLL and another one in the Application layer? could be, but I would make sure and think it twice over.
from my experience in one of my recent project (a weather web site with 200K unique visitors daily), we used link2sql for data access (mostly read only data), and simple data classes all over our ASP.Net MVC application (of course as part of models/view models). it worked quite smoothly, and we could easily change the data scheme without breaking down other layers.
as for your last question about DataTables, these objects, should you decide to use them (I would vote against), belong solely in your DAL. they should not be exposed to other layers as that would create coupling to that specific class. what if tomorrow MS invents a much better class? would you switch over now that you have a gazillion references all over your projects to the DataTables, its method and properties? would be nicer to just change your DAL to work with the NewAwsomeDataTable class and the rest of your app is blissfully ignorant.
hope that helped :)
I would use the following pattern as it allows you to upgrade to a different persistence strategy later.
UI/Consumer <--- (view models) --> BLL <--- Models ----> DAL/Persistence
Here the View models are consumed outside the BLL and models are communicated across the BLL/DAL layers.
In your case the model can be anything the DAL uses - DataTables for example or later perhaps ORM entities. The BLL is responsible to mapping between the model and view model.
As to keeping types in their own assemblies - yes for view models and in order to maintain a consistency, yes for the models as well.
Keeping the models and view models separate stops leakage of the persistence strategies outside of the BLL and thus permits future design changes to the persistence.
One advantage of this separation is that that different view model consumers can have differing view models for the same persistence model/entity. Some could be small and have few attributes and others large and rich in functionality. It also permits you to introduce offline/disconnectedness capability as the view models could be returned at differing times allowing you decide data merging strategies. This also allows you're persistence entities (e.g. tables to grow and change shape). Since this looks like a .net implementation things like AutoMapper will provide a lot of functionality out of the box
Of course this may be way overkill for your app - however I'd still maintain a BLL mapping that only talks view models to all BLL consumers. This should give you enough decoupling.
Pushing the domain entities into the dal is an option that would remove the crcular dependency, but may not match your intent. This isn't unheard of, though; for example LINQ-to-SQL gnerated entities would live in the DAL.
Other options:
put them into a common lower assembly (but that may leave your BL rather empty)
use IOC to remove / reverse the reference between BL/DAL
There are no single right answers here.
Re DataTable; personally I agree - I'm not a fan ;) However, they can be used successfully and reasonably. But if I had to use them, I'd be keeping them in the DAL as an implementation detail - and not exposing them above that.
Related
When I try to use DDD with .NET and C# my usual procedure is to construct one project for the Domain Model, another one for Data Access and another one for the application itself, like ASP.NET Web API. Usually there are more projects involved, but these three I usually work with.
My point here is that in the Domain Model project I put all business rules. There I define the Domain types (entities, value types, aggregates and so forth) and the repository interfaces.
My point then is that after I define the repository interfaces I implement then in a separate project. That project is the Data Access project. My reason for that is that to implement the data access I usually need technologies which do so (like ADO.NET, EF, Dapper and others).
I myself find it bad form to couple those dependencies on the Domain project for some reasons. I like the Domain project to be self contained and decoupled from any technologies.
On the other hand, I've heard sometimes that repositories might contain business rules and should be implemented inside of the Domain project.
Which approach is right? My approach which decouples the repositories implementation from the domain project in order to avoid coupling dependencies on technologies to the domain project or the approach which allows business rules inside repositories and thus makes repositories live inside the Domain project?
Where repositories really should be? In the domain project together with the domain types or in a Data Access project?
Your approach is correct. Repositories should be implemented in infrastructure layer.
On the other hand, I've heard sometimes that repositories might contain business rules and should be implemented inside of the Domain project.
The only responsibility of a repository should be persistence. If you end up with business logic in repositories, you should refactor them. Move the business logic to the domain model and keep the repositories in the infrastructure.
If you have business logic in queries, an easy way to deal with it in C# is to return IQueryable<T> from repositories. Then you can use LINQ to create queries in application or domain services. Some might argue that it is a leaky abstraction - you limit the implementation of repositories to data access technologies that work well with IQueryable. The ease of use very often makes it worth a try.
Repositories are the boundary that mediates between the domain and the data mapper. I would say that repository isn't about data access but just who translate the domain into some kind of data using the data mapper and also it does the inverse translation from the data to domain.
Instead of defining and implementing them outside the domain projects, if you want to leave them as tech-agnostic, maybe you can define repository interfaces on the domain project and create a Domain.[SomeTech] where SomeTech may be EF, Dapper, and so on, and where you're going to implement tech-specific repositories.
Now your application project will need to reference both Domain and, for example, Domain.EF projects.
BTW, based on my own experience, a good separation of concerns in terms of how the code files are organized is less important than how the solution is architected in terms of software layers.
That is, if your project is entirely using an OR/M like Entity Framework, the chance that you change it in the future is insignificant, thus, don't waste your time creating a solution of too many projects with few classes each them and focus yourself on a good separation of concerns in your code.
There's always time to split your projects, while a wrong architecture is just a waste of time.
Keep in mind that every codebase, every project, every domain is different. There are no hard-and-fast rules. Design the code to best fit what works for your project.
I've heard sometimes that repositories might contain business rules
If that's the case then they're not merely repositories. In a strictest sense, a repository just persists things to some storage.
Now, there can be business-driven logic inside the repositories which is still just persistence logic. And it's possible that this persistence logic would, in the standard 3-layer setup you describe, need to be duplicated in any other implementation of that layer. That's not the end of the world.
But it does beg the question that you're asking. And, as I said, there really are no hard-and-fast rules. You would need to decide for your project which rules you want to maintain and design the code around those rules.
For example(s)...
You might move this "business logic" into the models or other domain code and keep the repositories simple.
You might keep this "business logic" in the repositories and re-implement it in other repository implementations.
You might create a thin layer between the traditional domain and the simple repositories which applies this "business logic". You can think of these as domain-owned wrappers to the repository interfaces. The sole purpose of these objects, which aren't really business models but are conceptual logical types related to the repositories, is to contain specifically this logic.
In the end, it's really up to you. There is no right answer except the answer which makes the most sense for your codebase and results in simple, maintainable code.
There should be a logical separation in your representation of the Solution [*1] between those objects representing data management, human interaction, system interaction, and your Problem Domain (problem object model).
Physical separation (into say Projects) is entirely optional. Many would argue that it is a good organizational practice.
Data management objects (e.g. repositories) should only have functionality to persist and retrieve persisted data, not business logic or rules.
[*1] Includes both objects that model your problem (the "Problem Domain"), as well as all the supporting objects required to produce a complete working system.
Say i have 3 layers
layer 1: WPF Project (contains: xaml, viewmodels, mvvm framework)
layer 2: business logic layer (contains: plain c# classes)
layer 3: entity framework (contains: repository/data access classes)
when you dont want to expose your DAL(layer 3) to View(layer 1)
how do you implement the business logic layer well?
im having a hard time putting values back and forth the BLL objects and DAL entities.
can you please help?
Entity Framework doesn't work really well in a "disconnected" model. Unless something has changed, I've never been able to get it to work great easily.
You could use AutoMapper in Layer 2 to create ViewModels to present to Layer 1, but then you'd still have to send the changes back to Layer 3, which could be a pain.
If you're only developing a small app that will not change in the foreseeable, then just do whatever is quickest now. If you want a long-term maintainable app, then let me put forth the following.
The problem with this vertical layer approach is that whenever you need something in the view, you will have to add it to both the Business Layer (even if the business layer doesn't care about it), and the Data Layer. This requires your business layer to look like 1) UI views of the data 2) business views of the data and 3) the database representation of the data. That and/or you need a lot of mapping in-between layers. All of which dilutes business layer's actual purpose of representing business logic. What tends to happen then is that all the business logic gets migrated into transaction methods (that could just as well be static methods) to just change states on data objects. There's nothing at all wrong with that if your problem domain is nothing but CRUD with no complex logic. With complex logic, such business methods can get pretty tricky or even have undefined outcomes (because complex interdependencies on "fields" can be contradictory and hard to resolve).
Assuming you have complex logic, user views of data and business representations of data are often very different, and so UI views end up with specialized models of the data. If I were you, I just embrace this and use a simple version of the CQRS principle. That is, have the data for your UI views come from a different place than where your business operations are executed. In your case, I might have an EF Model in your DAL that only services your UI views, and gives them exactly what they need (whether by database views, stored procedures, or pre-compiled report tables). Then create a separate EF model that services only the needs for your Business entities. Then when you are ready to perform an actual business action, the UI's viewmodel action method can load the business object from the business EF model (or better yet, call an object factory from the business layer which does this) and run an appropriate action on the business object. Note that I'm also making the assumption here that your database is highly relational (mostly 2nd and 3rd normal form) and you are set on using EF.
I would not try to make your View Models into business logic. This makes your business logic not easily reusable on other platforms or applications (like web). MVVM should only service the UI. In my mind, the V (view) represents what the user sees and operates. The M (model) represents what the user chose on that view. And the VM (view model) translates between the two. Your program should then take the user's validated choices (UI model) and extract the needed data out of it to perform an appropriate business operation.
Instead of exposing all of your DAL to View Layer, just exchange your domain objects (EF objects) between all layers. The structure may be similar to the following:
Presentation Layer-------- ^
BLL --------------------------- | Data objects
DAL (Repositories etc.)--- |
So, all of your layers will be disconnected; but they will share the same domain objects. In real world, you can implement a similar structure by creating a seperate dll for Entity Framework entities which is shared by all layers. Note that ObjectContext shall be only visible to DAL (by default, entities and object context are generated in the same dll, you need to seperate this into two dlls).
In addition to the answer by Daryal, you can define your business-objects in your BL to be POCO's, and use EF in your DAL layer to read them from or persist them to the database.
If you define an repository-like interface in your BL (or unit-of-work, whatever naming you give it), and implement the interface in your DAL, then all you need is a little DI to get an instance of the repository-class without having to reference the DAL all the time. It works like a charm for me.
See here and here for more information.
Your ViewModels are your application in MVVM, so they should be handling things like data access through your Repository classes, or business logic (either directly, or indirectly using your validation classes).
If you don't want to directly reference the classes, use an Interface but be aware that you'll need to have some way of passing your inherited class to your ViewModel. I once did a project where we had a library of shared interfaces, such IRepository interfaces, and everything was imported/exported using MEF so the layers didn't reference each other directly.
The final (simplified) layout was:
Models -> Contained plain data objects that could do simple validation on their own data (length, min/max values, etc) but that didn't do any advanced validation or business logic. Did not reference any other library.
Common -> Contained interfaces, utilities, and other commonly shared classes. Referenced the Model library only.
DAL -> Contained Data Access and Repositories based on repository interfaces found in Common library. Referenced Common library for interface definitions and utilities, and Model library because it contained the data models used or returned in data access calls
ViewModels -> Contained application and business logic. Referenced Common for its utilities and interfaces, and Models for the data models
Client -> Contained Views. Referenced Models and ViewModels so it could write DataTemplates for both object types
Entity framework is suppouse to be used as "Logic Layer" by itself.
Your idea may have some sense, to use combine technologies.
Howevere, I think some of those Micros. libraries, where designed to be used separately, unless, otherwise explicitly combined & mentioned in their websites.
Good Luck.
I second daryal and I have implemented this in some projects. It is absolutely OK to use POCO as business objects.
Another approach instead of creating 2 projects (one for DB Context and one for Entities) is to use one DAL/DATA project only and reference it in BLL. Then inherit the POCO class in BLL and use that class in UI layer. Below is the basic sample code:
// assume this is EF generated POCO
namespace Owner.Project.Data{
public partial class Product
{
public int ProductId { get; set; }
public string ProductName { get; set; }
}
}
// this is manually created class in BLL
using Owner.Project.Data;
namespace Owner.Product.Business{
public class StoreProduct : Product {
public bool Add (string productName){
// TODO - add product using EF as you normally do
}
}
}
Now you can reference the BLL in your UI project and use StoreProduct class there. To achieve loosely coupled pattern, Of course you could also inherit the StoreProduct class from an IStoreProduct interface and make use of it in UI or web service but that is another topic.
I Am creating a web application and first use Entity Framework. I created Entity Data Model and now I am not sure, how to proceed now.
Premise: My database is really simple (Rating, WebPage, Visitor) and database tables corresponds to the business objects.
My suggestion is 3tier architecture but how to make it?
It is good idea create partial classes with the same name as Entity Framework objects (Rating, Visitor) and declare here new methods (GetAverageRating()...)? Or is better create some VisitorProvider, RatingProvider and place logic here?
It is better use EF objects in BLL and Presentation Layer or I should create my own BO objects on my BLL layer and transform EF object to BO?
I'm think, it is more practical use static methods on my DAL than instantiate classes on BLL. Do you agree?
Can you recommend me some best practices? I have many ideas how to create it, but I do not know what is the right.
3 layer architecture is quite popular but what it really means?
Presentation layer
Application layer
Database layer
If you ask what each layer means you can be pretty sure you will get several different answers. You can further divide each layer into sublayer and build layered hell like:
Client side presentation layer
Server side view layer
Controller layer
Service facade layer
Service layer
Domain objects layer
Repository + Factory layer
ORM layer
Stored procedure layer
Database view layer
Database table layer
WTF? That is just example that application can be easily over architected. It can go even worse if you insist that only neighbours can exchange data and if you decide to add special type of objects to be exchanged between layers instead of flowing sing set of objects through multiple layers.
Add layers which you need to make you more comfortable with developing the application and which will do reasonable separation of concerns and maintainability needed for the scale of your application. You can simply do the most simplest application which will be used just few weeks and must be developed as fast as possible. In such case you can do that within few days simply by using ASP.NET web forms and data source controls (or ASP.NET dynamic data). It can be badly extensible but in such situation it is exactly what you need to implement application quickly. Writing layers and doing all the stuff around maintainability and extensibility is reasonable if you need it. Another quick prototyping technique is ASP.NET MVC Scaffolding which can create quick multilayered skeleton of the application which can be further modified.
Both approaches are correct and it only depends on the approach you like. The first is called active record pattern but it is not used very often with entity framework. The second approach is more popular. You can either use EF directly in some middle class which you called Provider (common name is also Service). This class will do both data access logic and business logic. In more complex applications developers like to somehow wrap EF to separate class following repository pattern and call the repository either from service or directly from web app. code behind or controller (depending on amount of business logic). Try to do it without repository first. My personal opinion is that people should start to use repository only once they understand EF itself.
Again both approaches are correct. In a simple application it is fully acceptable to create EF model with POCO classes (EFv4.x) and use them in all layers. If you are using ASP.NET MVC you can find that you need special classes as view models to fully represent needs of your individual views. In a more complex application you can have separate objects exposed from a business layer - this is especially used if the business layer is exposed as a remote service (WCF).
It depends how you write these DAL methods - it is absolutely necessary to not share the EF context among requests! It also depends if you want to write some test or not. Layer defined by static methods is something which goes directly against testable architecture where you want unit test just single layer (unit testing with EF can be hard). It also depends if you want to use dependency injection which is based on instances.
I'm working on a small application from scratch and using it to try to teach myself architecture and design concepts. It's a .NET 3.5, WPF application, and I'm using Sql Compact Edition as my data store.
I'm working on the business logic layer, and have just now begun to write the DAL. I'm just using SqlCeComamnds to send over simple queries and SqlCeResultSet to get at the results. I'm starting to design my Insert and Update methods, and here's the issue - I don't know the best way to get the necessary data from the BLL into the DAL. Do I pass in a generic collection? Do I have a massive parameter list with all the data for the database? Do I simply pass in the actual business object (thus tying my DAL to the conrete stuff in the BLL?).
I thought about using interfaces - simply passing IBusinessObjectA into the DAL, which provides the simplicity I'm looking for without tying me TOO tightly to current implementations. What do you guys think?
I don't think there is a simple answer to your questions because there are many options depending on the circumstances. I have found it helpful to read the two books below to help me understand the problems you describe better.
MS .NET: Architecting Applications for the Enterprise (Esposito, Saltarello)
MS Application Architecture Guide, 2nd edition.
The second book is available online. Look here.
I think it is OK to pass the Business object to the Data Access Layer. I think the BLL's job is just to work with its objects, to check if all rules are being followed, about what can be saved, by whom, on what fields, time, etc.
Once it has done that it should pass it to the DAL, and I think it is IT'S job to figure out how to convert what it got into something that can be persisted, but it wont check what is being persisted or read or by whom, it will just do it. This could be straight foward, a la linq, but if your logic mdoels do not match your data model 1:1, then the DAL should do all the conversion.
About tying your DAL to the stuff in the BLL, I think you should worry about the other way around, tying your BLL to your DAL. I would use an interface to represent your DAL (as in IRepository) that way you can make your BLL call any kind of persistance mechanism just by changing the type of IRepository it is using (extra points if you use IoC :P). The concrete classes that implement the IRepository would be tied to the business objects, but they have to know what is it that they are saving don't they? while the BLL does NOT have to know what is doing the saving.
To pass business object in the DAL is the simpler and fastest method. It works in small projects, but have same disadvantages:
1) Business Objects are part of BLL layer, and if you pass objects in BLL then DAL becomes dependent of BLL. low layer knows about upper one - this contradicts the idea of layers at all.
2) Business Object are usially very complex to save it directly in BD. In this case it is better to introduce new "Mappers" intermediate layer.
To overcome all these issues I usially make interface to DAL independent of Business Objects. I use "Row" classes instead - representation of one record in the database or XML. In .NET 3.5 linqtosql autogenerated classes can be used for this purpose.
If I was in your position, I'd probably use LINQ to SQL to define my data access layer - it'll save you lots of work maintaining all that SqlCeFooBar stuff and give you a designer (of sorts) for maintaining your database that you would otherwise lack, using SQL CE.
So in that case, I'd probably couple the business logic layer pretty tightly to the entities exposed by the L2S layer. The justification being that the entities are the business objects, albeit devoid of any services.
I probably wouldn't let the entities get as far up the hierarchy as the UI though. At that level, it makes much more sense to use a model specifically for the view - especially given that you're using WPF.
Of course, all of this depends upon the size and complexity of your application. I'm assuming it's a fairly small scale application (single user?) given that you're using SQL CE.
So i am reorganizing a winforms C# solution to help decouple and make it cleaner and more organized. The solution tracks a small business orders,etc . .
I have broken out the projects so far into
App.View - all GUI Related Code
App.Data - just data structures and interfaces. No other implementation code
App.BusinessLogic - all business logic code that has no GUI references
I have some classes that i can't figure out where they belong. Please let me know your thoughts which project each class should go or if there is another project that should get created for this.
A Class that retrieves user preferences from a database
A Class that retrieves static data from our static data server and returns sets of data results.
A Class that brings down user entitlements
A model class that stores a hashtable of orders
A class that emails out messages on a user action
Actually, I think you have things a little off from a traditional layered architecture. Normally, the models of your data that your application works on would be kept in a business layer, along with the code to operate on them. Your data layer would have both the data models of your persistence framework and the code to interact with that framework. I think this might be the source of the confusion between the suggested locations of your classes and your reaction to it based on your comments.
From that perspective anything that retrieves or brings would necessarily be located in your data layer -- it's accessing data in persistent storage. What it retrieves are eventually converted into business layer objects that your business logic operates on. Things are are conceptual models -- like a table of orders -- or business actions belong in the business layer. I would agree with #Adron with, perhaps, the same confusion about where (3) goes depending on what it actually is.
More specifically:
User Preferences are business
objects, the thing that retrieves
them is a data layer object.
The static data maps on to a business
object (table or view or something),
the thing that accesses the external
server is a data layer object.
The user entitlement is a business object, the thing that retrieves it is data layer object.
A table of Orders is a business object
Emailing is a business activity, so the thing that mails people is a business object
[EDIT] My generalized 3-Tier Architecture for (simple) web apps
DataAccessLayer
This would include my TableAdapters and strongly typed DataTables and Factories that turn rows of my DataTables into business objects in pre-LINQ projects. Using LINQ this would include my DataContext and designer generated LINQ entities.
BusinessLayer
This would include any business logic, including validation and security. In pre-LINQ these would be my business objects and any other classes that implement the logic of the application. Using LINQ these are the partial class implementations of my LINQ entities to implement security and validation along with any other classes to implement business logic.
Presentation
These are my web forms -- basically the UI of the app. I do include some of the validation logic in the forms as an optimization, although these are also validated in the BL. This would also include any user controls.
Note: This is the logical structure. The project structure generally mirrors this, but there are some cases, like connections to web services, that may be directly included in the web project even though logically the components are really in the BL/DAL.
Note: I'll probably be moving to MVC over 3-Tier once ASP.NET MVC is in production. I've done some personal projects in Ruby/Rails and I really like the MVC paradigm for web apps.
You have specified that App.Data should contain only data structures and interfaces, no implementation code, which is fine if you want to do that, but that leaves you with nowhere to put your database access code except in your App.BusinessLogic assembly.
Perhaps you really need to rename App.Data to App.Model (or something similar), and have a new App.DataAccess assembly that talks to the database (perhaps implementing a Repository pattern). Having done that, I would split things up like this:
App.DataAccess
App.DataAccess
App.DataAccess
App.Model
App.BusinessLogic
I would probably go with
Data
Data
Data, although I'm not entirely sure what the class is doing
Data
BusinessLogic
-> App.Data
-> App.Data
-> App.BusinessLogic or App.Data - not sure exactly what this means.
-> App.BusinessLogic
-> App.BusinessLogic