I am using a repository design with web applications (repository (data layer) exposing model (objects) to the business layer which is then consumed to the data layer (ui). Objects or lists of objects are passed between the layers with this type of implementation.
I am finding my business layer is a becoming a series of manager type classes which all have common GetAll, GetById, Save, Delete type methods. This is very common with a number of very small simple objects. This is the area of concern or opportunity for improvement (the series of smaller business manager classes). I am looking for options to avoid the whole series of smaller business manager classes mapping to the smaller objects which only do get/save/delete object.
The bigger objects which are closer to the functionality to the application have a number of methods in addition to the get/save/delete type methods (these manager classes are ok).
I am thinking there is a design pattern or implementation which will allow me to have one manager class which resides in the business layer which would accept an object as a parameter of a particular object type and the get/save/delete methods respectively know the type of repository object to spin up and pass the object to it for its operation.
The benefit here would be that I can have one generic manager class to pass save/delete/get's for smaller type objects to the appropriate repository class thereby reducing the many smaller manager classes.
Ideas on how to accomplish this?
thx
I would not go that way. The business layer classes can be as simple as code that forwards to the data layer, and it is true that they can be annoying to write, but they exist for a couple of reasons: validation, security, taking some actions based on business rules.
If you try to make a generic business layer, it will hard to include all the various things that a business class could do. The generic business layer will become much more complex than the one you currently have. Testing will be much harder. Adding a new business rule will be hard, too.
Sorry, this is not what you wanted to read, but I have already gone the route of generic systems and have always had lots of regrets.
The idea behind a repository (or a dao), is to further abstract data access concerns away from the business layer in order to simplify that layers focus on the "business" of a given domain.
That said, there are many common plumbing type of concerns that are reuseable across different applications, some of which do lend themselves to a supertype in the business layer. Consider the cross cutting concern of being able to retrieve a given business entity by some Id from a database, and you might come to the conclusion that it is in fact useful to have an Id property in a business layer supertype. It might even be useful if entities considered that Id when determining equality. Etc..
Now I do believe that Timores is right in principal and trying to write one application that fits all domains is both incredibly painful and totally fruitless, but I also beleive the the art of the profession is knowing how to use a variety of tools and when to apply which one, and having some core infrastructure code should be in your tool belt.
For a good idea of a framework concept for a web app that has been road tested, take a look at SharpArch.
HTH,
Berryl
Related
I am embarking on a new project and I need some guidance from veteran architects/design pattern gurus!
My new project needs to have a number of persistence layers whereby the client can decide at runtime where the data will be stored, for example, in house SQL database, MS Exchange or Google storage.
The functionality will essentially be the same just the storage/implementation of each will be different.
What I'm not looking for a here is how you do it just a pointer to the best patterns to use to serve my purpose whilst still providing flexibility down the road as their will be CHANGE. I am trying to avoid concrete implementations that will inevitably lead to some nasty code smells.
I know it will involve some kind of DI along the way but any pointers here would be greatly appreciated.
There is nothing special with your case really, so if you would follow standard practices with DI and use container to ease your task like SimpleInjector that will do the trick. The main point for you should be to not depend on concrete classes but on abstraction and that's where DI-container will help you organize this.
E.g. if you plan to save user you might have some IUserRepository with a method SaveUser. Then you will implement SqlUserRepository, GoogleStorageRepository, etc. The same goes for any other data access layer interface. If you just do that, you will need to configure your DI in a way where you can supply the required repository at a runtime based on your needs. Do not forget to never depend on GoogleStorageRepository, etc. directly, but only on a common interface. I would create a project for interfaces (and corresponding BI data model that DL will be aware of) and a project per each implementation as well to separate it even further.
Repository pattern is all about creating a separation between the persistence layer and the business layer.
Many examples on the web demonstrates it incorrectly by just using it as an wrapper over their data entities. That is incorrect. The design of a repository class/interface should be driven by the business requirements and not from how the first data store looks like.
Thus it's a perfect pattern for your use case. You define an repository interface from the business layer perspective and then create an implementation for each data store like MSSQL. I even put that interface in my business layer to further demonstrate that perspective.
I have a project with the following structure:
Project.Domain
Contains all the domain objects
Project.EntityFramework, ref Project.Domain
Contains Entity Framework UnitOfWork
Project.Services, ref Project.Domain and Project.EntityFramework
Contains a list of Service classes that perform some operations on the Domain objects
Project.Web.Mvc, ref to all the projects above
I am trying to enforce some Business rules on top of the Domain objects:
For example, you cannot edit a domain object if it's parent is disabled, or, changing the name of an object, Category for example, needs to update recursively all it's children properties (avoiding / ignoring these rules will result in creating invalid objects)
In order to enforce these rules, i need hide all the public properties setters, making them as internal or private.
In order to do this, i need to move the Project.Services and Project.EntityFramework inside the Project.Domain project.
Is this wrong?
PS: i don't want to over complicate the project by adding IRepositories interfaces which would probably allow me to keep EntityFramework and Domain separate.
PS: i don't want to over complicate the project by adding IRepositories interfaces which would probably allow me to keep EntityFramework and Domain separate.
its really a bad idea, once i had this opinion but honestly if you dont program to abstraction it will become a pain when the project becomes larger. (a real pain)
IRepositories help you spread the job between different team members also. in addition to that you can write many helper extensions for Irepository to encapsulate Different Jobs for example
IReopisotry<File>.Upload()
you must be able to test each layer independently and tying them together will let you only do an integration tests with alot of bugs in lower layers :))
First, I think this question is really opinion based.
According to the Big Book the domain models must be separated from the data access. Your domain has nothing to with the manner of how storing the data. It can be a simple text file or a clustered mssql servers.
This choice must be decided based on the actual project. What is the size of the application?
The other huge question is: how many concurrent user use the db and how complex your business logic will be.
So if it's a complex project or presumably frequently modified or it has educational purposes then you should keep the domain and data access separated. And should define the repository interfaces in the domain model. Use some DI component (personally I like Ninject) and you should not reference the data access component in the services.
And of course you should create the test projects also using some moq tools to test the layers separately.
Yes this is wrong, if you are following Domain Driven Design, you should not compromise your architecture for the sake of doing less work. Your data-access and domain should be kept apart. I would strongly suggest that you implement the Repository pattern as it would allow you more flexibility in the long run.
There are of course to right answer to whats the right design...I would however argue that EF is you data layer abstraction, there is no way youre going to make anything thats more powerful and flexible with repositories.To avoid code repetition you can easily write extension methods (for IQueryable<>) for common tasks.Unit testing of the domain layer is easily handled by substituting you big DB with some in-proc DB (SqlLite / Sql Server Compact).IMHO with the maturity of current ORMs like nHibernate and EF is a huge waste of money and time to implement repositories for something as simple as DB access.
Blog post with a more detailed reply; http://ayende.com/blog/4784/architecting-in-the-pit-of-doom-the-evils-of-the-repository-abstraction-layer
I'm trying to structure my WPF MVVM application according to best practises. I have to start with a lot of existing code so don't have the option of resolving all structural flaws straight away. I like the following solution structure.
http://www.paulspatterson.com/technology/dot-net-development/mvvm-and-wpf-for-vb-net-series-2-part-1-again/
This separates the solution into the following projects; BusinessLogic, BusinessObjects, Infrastructure (Common reusable utilities), WPF Shell and Modules (application components to be injected using an IOC container).
I understand that the business object represents the human world entity whereas the business logic is the implementation details as discussed in this question.
What are Business Objects and what is Business Logic?
Therefore using MVVM does the business object just become a dumb container that doesn't actually do anything other than wait to have its properties changed by external business logic? I don't see how you decouple the business object from the business logic to the point of being able to have them in separate assemblies.
Take the following hugely simplified code:
public class Chart
{
private SizeChart _activeChartSize = new SizeChart();
public void Draw() {
// Size the chart object
_activeChartSize.Size(this);
// Do other draw related things
}
}
public class SizeChart
{
public void Size(Chart chartToSize) {
// Manipulate the chart object size
}
}
In the context of the MVVM solution structure described above (to my mind at least) the SizeChart class would be business logic and the Chart class would be a business object but placing them in different projects would be a circular dependency. Is the SizeChart class business logic or a business object and where in the solution structure should the SizeChart class reside if I adopt this proposed MVVM solution structure?
Apologies if this is an incredibly obvious and simple question to some people but it's difficult when you can't start with a clean slate to know how to best start transitioning poorly structured code to well structured code.
http://en.wikipedia.org/wiki/Business_object
Business Object: A type of an intelligible entity being an actor inside the business layer in an n-layered architecture of object-oriented computer programs.
Whereas a program may implement classes, which typically end in objects managing or executing behaviors, a business object usually does nothing itself but holds a set of instance variables or properties, also known as attributes, and associations with other business objects, weaving a map of objects representing the business relationships.
http://en.wikipedia.org/wiki/Business_logic_layer
Business Logic Layer : A business logic layer (BLL), also known as the domain layer, is a software engineering practice of compartmentalizing.
Within a BLL objects can further be partitioned into business processes (business activities) and business entities. Business process objects typically implement the controller pattern, i.e. they contain no data elements but have methods that orchestrate interaction among business entities.
So basically a business object models an entity (usually a real world object such as Employee or Account) whereas business logic facilitates the interaction between business objects and between other application layers.
I think the most appropriate answer was given by Daniel Hilgarth. His answer was don't separate the business logic from its objects, because this leads to an anemic domain model.
While I think the following WPF MVVM solution structure proposed by Paul S Patterson is a good one I don't think it's appropriate for everyone.
http://www.paulspatterson.com/technology/dot-net-development/mvvm-and-wpf-for-vb-net-series-2-part-1-again/
The creation of distinct Business Logic and Business Object projects probably works best if your business objects are Data Transfer Objects (DTOs) e.g. Linq to SQL rather than a more complex object such as a composite that may have tighter coupling to the business logic.
Business object is a rather amorphous term - is it a DTO, a POCO, or a mix of that with some business logic thrown in?
To me, I would consider something different - Chart and SizeChart are both controls rather than "business objects" or "business logic". It's not the fact that they have UI sounding function names in them, but that they are actually doing UI or rendering related work (sizing and drawing). The collection of data that these work with would be separate and would be assigned to the controls before invoking Size or Draw.
Note that this answer is agnostic of MVVM as it is a bit of a red herring - your question is more closely related to general n-tier design in which you also incorporate MVVM.
I ran into something similar on a project recently.
We have a web app that allows an administrator to create groups. One of the rules that was required was that you couldn't create two groups of the same name. What we ended up doing was creating a very basic object, a Group, and then creating a service called GroupService. GroupService does the rule checking so that when a user calls GroupService.Save(Group), the service goes out and checks for prior groups with the name. If the name is found, an error is given back to the user and the save doesn't occur.
In our case, the hierarchy is Controller has Services, Services have Repositories, and Repositories finally commit to the database. Running throughout each of these abstractions is the model, Group. But our model isn't just a 'dumb' object. It does contain the validation logic on the data fields themselves and has aggregate properties to simplify databinding.
Expanding this to the MVVM conecept, I would think the View Model would have the service that contains the business logic and a model that was to be incorporated into the View. Obviously the View would be bound to the ViewModel, but the ViewModel would have some instance of the Model object to bind to.
I’m trying to reevaluate our n-layer architecture and would love to get some suggestions based on your experiences. Here is our typical .NET n-layer (sometimes n-tier) design.
Project.UI
Project.Services
Project.Business
Project.Model
Project.DataAccess
DataAccess typically consists of Entity Framework 4 and Repository classes. I attempt to follow the Aggregate Root concept in order to avoid having a repository for table, easier said than done in my experience. I tend to have ~70% match between Repositories and Tables.
Model usually consists of my Entity Framework 4 entities, I've been using Self-Tracking EF entities with success.
Business is what I struggle with the most. I typically have a Manager class for every Repository. This class will contain methods like .Add() which will perform business validation before forwarding down to repository.Add().
Services, typically I will only implement this if in fact I am looking to create a web service based solution. This layer will be tasked with marshaling requests/responses between DTOs and entities. And most importantly provide the more coarse grained interface. For example a TradingService.SubmitTrade(), which is really a facade for a business transaction which might include AccountManager.ValidateCash(), OrderManager.SubmitOrder(), etc.
Concerns
My business layer is very entity centric, really it's just the glue between the entities and the repository, with validation in between. I've seen many designs where the Service Layer is what holds a reference to the repositories (in essence skipping the "business layer"). In essence it serves the same purpose as my Business layer, it does the validation, however its' responsibility (and naming) is a higher level, more coarse grained business transaction. Using the example above the TradingService.submitTrade() will not delegate to any business manager classes, it would itself query the necessary repositories, perform all the validation etc.
I like my design in a sense that I can reuse a business layer method in multiple service calls, however I hate the fact that for every repository I have a matching business layer manager, creating tons of extra work. Maybe the solution is a different type of grouping at the Business Layer level? For example combine individual Manager classes like PhoneManager and EmailManager (note I have Phone entities and Email entities) into a logical Manager class such as ContactsManager (note I don't have a "Contact" entity type). With methods such as ContactManager.GetPhones() and ContactManager.GetEmail(), etc.
I guess more than anything I am wondering how others organize and delegate responsibilities, whether they have the Service layer, Business layer, both, etc. What holds the ORM context reference, etc.
I tend to do what you outlined near the end of your concerns, and at the business layer group things into managers that make more logical sense from a business point of view.
Using Contacts for example, I certainly wouldn't have a PhoneManager or EmailManager. "ContactsManager" is a more useful grouping to me, accomplishing pretty much the same thing only with a lot fewer managers to deal with. From a business point of view, phone numbers and emails are just small pieces of a Contact anyway. Just because they have their own tables and entities doesn't mean they need their own manager. That doesn't mean that you can't reuse them. If you have a need to do work with email addresses in several places, ContactsManager can have the relevant methods.
What we tend to have in our environment is a database/entity layer, then a business layer that sits on the server and handles business rules and business logic. That business layer is exposed as a service via WCF to the client (or at least, stuff relevant to clients is).
It sounds like you already know what you want to do, so I'd suggest doing a bit of prototyping work on it and see how it works for you. :)
Something on my mind about structuring a system at a high level.
Let's say you have a system with the following layers:
UI
Service Layer
Domain Model
Data Access
The service layer is used to populate a graph of objects in the domain model. In an attempt to avoid coupling, the domain model will be not be persistence aware and will not have any dependencies on any data access layer.
However, using this approach how would one object in the domain model be able to call other objects without being able to load them with persistence, thus coupling everything together - which I'd be trying to avoid.
e.g. an Order Object would need to check an Inventory object and would obviously need to tell the Inventory object to load in some way, or populate it somehow.
Any thoughts?
You could inject any dependencies from the service layer, including populated object graphs.
I would also add that a repository can be a dependency - if you have declared an interface for the repository, you can code to it without adding any coupling.
One way of doing this is to have a mapping layer between the Data Layer and the domain model.
Have a look at the mapping, repository and facade patterns.
The basic idea is that on one side you have data access objects and on the other you have domain objects.
To decouple you have to: "Program to an 'interface', not an 'implementation'." (Gang of Four 1995:18)
Here are some links on the subject:
Gamma interview on patterns
Random blog article
Googling for "Program to an interface, not an implementation" will yield many useful resources.
Have the domain model layer define interfaces for the methods you'll need to call, and POCOs for the objects that need to be returned by those methods. The data layer can then implement those interfaces by pulling data out of your data store and mapping it into the domain model POCOs.
Any domain-level class that requires a particular data-access service can just depend on the interface via constructor arguments. Then you can leverage a dependency-injection framework to build the dependency graph and provide the correct implementations of your interfaces wherever they are required.
Before writing tons of code in order to separate everything you might want to ask yourself a few questions:
Is the Domain Model truly separate from the DAL? And yes, I'm serious and you should think about this because it is exceedingly rare for an RDBMS to actually be swapped out in favor of a different one for an existing project. Quite frankly it is much more common for the language the app was written in to be replaced than the database itself.
What exactly is this separation buying you? And, just as important, what are you losing? Separation of Concerns (SoC) is a nice term that is thrown about quite a bit. However, most people rarely understand why they are Concerned with the Separation to begin with.
I bring these up because more often than not applications can benefit from a tighter coupling to the underlying data model. Never mind that most ORM's almost enforce a tight coupling due to the nature of code generation. I've seen lot's of supposedly SoC projects come to a crash during testing because someone added a field to a table and the DAL wasn't regenerated... This kind of defeats the purpose, IMHO...
Another factor is where should the business logic live? No doubt there are strong arguments in favor of putting large swaths of BL in the actual database itself. At the same time there are cases where the BL needs to live in or very near your domain classes. With BL spread in such a way, can you truly separate these two items anyway? Even those who hate the idea of putting BL in a database will fall back on using identity keys and letting the DB enforce referential integrity, which is also business logic..
Without knowing more, I would suggest you consider flattening the Data Access and Domain Model layers. You could move to a "provider" or "factory" type architecture in which the service layer itself doesn't care about the underlying access, but the factory handles it all. Just some radical food for thought.
You should take a look at Martin Fowler's Repository and UnitOfWork patterns to use interfaces in your system
Until now I have seen that application can be well layered into three layers: Presentation-->Logic-->Data--and Entities (or Bussines Object). In the Logic Layer case you can use some pattern such as Transaction Script or Domain Model I'm supposing you're using this last. The domain model can use a Data Mapper for interacting with the data layer and create business objects, but you can also use a Table Module pattern.
All this patterns are described in Marttin's Fowler Patterns of Enterprise Application Architecture book. Personally I use Transaction Script because it is simplest than Domanin Model.
One solution is to make your Data Access layer subclass your domain entities (using Castle DynamicProxy, for example) and inject itself into the derived instances that it returns.
That way, your domain entity classes remain persistence-ignorant while the instances your applications use can still hit databases to lazy-load secondary data.
Having said that, this approach typically requires you to make a few concessions to your ORM's architecture, like marking certain methods virtual, adding otherwise unnecessary default constructors, etc..
Moreover, it's often unnecessary - especially for line-of-business applications that don't have onerous performance requirements, you can consider eagerly loading all the relevant data: just bring the inventory items up with the order.
I felt this was different enough from my previous answer, so here's a new one.
Another approach is to leverage the concept of Inversion of Control (IoC). Build an Interface that your Data Access layer implements. Each of the DAL methods should take a list of parameters and return a Data Table.
The service layer would instantiate the DAL through the interface and pass that reference to your Domain Model. The domain model would then make it's own calls into the DAL, using the interface methods, and decide when it needs to load child objects or whatever.
Something like:
interface IDBModel {
DataTable LoadUser(Int32 userId);
}
class MyDbModel : IDBModel {
DataTable LoadUser(Int32 userId) {
// make the appropriate DB calls here, return a data table
}
}
class User {
public User(IDBModel dbModel, Int32 userId) {
DataTable data = dbModel.LoadUser(userId);
// assign properties.. load any additional data as necessary
}
// You can do cool things like call User.Save()
// and have the object validate and save itself to the passed in
// datamodel. Makes for simpler coding.
}
class MyServiceLayer {
public User GetUser(Int32 userId) {
IDBModel model = new MyDbModel();
return new User(model, userId);
}
}
With this mechanism, you can actually swap out your db models on demand. For example, if you decide to support multiple databases then you can have code that is specific to a particular database vendors way of doing things and just have the service layer pick which one to use.
The domain objects themselves are responsible for loading their own data and you can keep any necessary business logic within the domain model. Another point is that the Domain Model doesn't have a direct dependency on the data layer, which preserves your mocking ability for independent testing of business logic.
Further, the DAL has no knowledge of the domain objects, so you can swap those out as necessary or even just test the DAL independently.