Abstracting the DataLayer (DAL) of a three-tier application - c#

As continuation to my previous question, (see https://stackoverflow.com/questions/3737848/creating-a-loosely-coupled-scalable-software-architecture
Someone suggests to also Abstract the DAL like I abstracted the BLL from the Presentation Layer on my three tier project. Any suggestion on how to do this? Do I also need a factory between the BLL and the DAL? I need your input guys.. thanks.

Interesting - I'd put abstraction between the BL and DAL way before I'd do that for the presentation layer.
The approach used in your other question seems reasonable - why don't you just reuse that?
Yes you need a factory; but you can include this in a common class / assembly and have it just return a object, which you can then cast as it's returned - i.e: at the point in the BL where it's being called.
(for completeness:) using Activator.CreateInstance() (as you've used in your other question) is the right way to go.
For DAL I tend to use values stored in the config (as arguments to pass into the factory); it's not common to change the DAL implementation that often - so config works well for me.
Observe the Interface Segregation Principle (ISP) when designing the contractr / abstraction between the BL and DAL - if you do it right you'll be able to mix-and-match different physical DAL implementations at once.
If you keep the DTO's and factory in a common assembly (possibly the same one) then it's easy to re-use them with the BL and various DAL implementation - with the caveat that you keep this common class as devoid of dependancies as possble. If you do this you'll be able to add / udpate DAL implemenations without re-compiling and re-deploying the whole system.

Related

How to change persistence layer at runtime in C#

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.

3 Tier Architecture with NHibernate, Ninject and Windows Forms

So I'm in the middle of rafactoring a small to medium sized Windows Forms application backed by a SQLite database accessed through NHibernate. The current solution contains only an App Project and Lib Project so it is not very well structured and tightly coupled in many places.
I started off with a structure like in this answer but ran into some problems down the road.
DB initialization:
Since the code building the NHibernate SessionFactory is in the DAL and I need to inject an ISession into my repositories, I need to reference the DAL and NHibernate in my Forms project directly to be able to set up the DI with Ninject (which should be done in the App Project / Presentation Layer right?)
Isn't that one of the things I try to avoid with such an architecture?
In an ideal world which projects should reference eachother?
DI in general:
I have a decently hard time figuring out how to do DI properly. I read about using a composition root to only have one place where the Ninject container is directly used but that doesn't really play well with the current way NHibernate Sessions are used.
We have a MainForm which is obviously the applications entry point and keeps one Session during its whole lifetime. In addition the user can open multiple SubForms (mostly but not exclusively) for editing single entities) which currently each have a separate Session with a shorter lifetime. This is accomplished with a static Helper exposing the SessionFactory and opening new Sessions as required.
Is there another way of using DI with Windows Forms besides the composition root pattern?
How can I make use of Ninjects capabilites to do scoped injection to manage my NHibernate Sessions on a per-form basis (if possible at all)?
Terminology:
I got a little confused as to what is a Repository versus a Service. One comment on the posted answer states "it is ok for the repository to contain business-logic, you can just call it a service in this case". It felt a little useless with our repositories only containing basic CRUD operations when we often wanted to push filtering etc. into the database. So we went ahead and extended the repositories with methods like GetByName or more complex GetAssignmentCandidates. It felt appropiate since the implementations are in the Business Layer but they are still called repositories. Also we went with Controllers for classes interacting directly with UI elements but I think that name is more common in the Web world.
Should our Repositories actually be called Services?
Sorry for the wall of text. Any answers would be greatly appreciated!
Regarding 1:
Yes and no. Yes you would prefer the UI Layer not to be dependent on some specifics of x-layers down. But it isn't. The composition root is just residing in the same assembly, logically it's not the same layer.
Regarding 2:
Limit the usage of the container. Factories (for Sessions,..) are sometimes necessary. Using static should be avoided. Some Frameworks however prevent you from using the ideal design. In that case try to approximate as much as possible.
If you can currently do new FooForm() then you can replace this by DI or a DI Factory (p.Ex. ninject.extensions.Factory). If you have absolutely no control on how a type is instanciated then you'll need to use static to access the kernel like a service locator and then "locate" direct dependencies (while indirect dependencies are injected into direct dependencies by the DI container).
Regarding 3: i think this is somewhat controversial and probably often missunderstood. I don't think it's really that important what you call your classes (of course it is, but consistency across your code base is more important than deciding whether to name them all Repository or Service), what's important is how you design their responsibilities and relationships.
As such i myself prefer to extract filters and stuff in the -Query named classes, each providing exactly one method. But others have other preferences... i think there's been enough blog posts etc. on this topic that there's no use in rehashing this here.
Best practice to implement for situation like yours is to use MVP design pattern. Here its the architecture that i can offer to you.
MyApp.Infrastructure // Base Layer - No reference
MyApp.Models // Domain Layer - Reference to Infrastructure
MyApp.Presenter // Acts like controllers in MVC - Reference to Service, Models,
MyApp.Repository.NH // DAL layer - Reference to Models, Infrastructure
MyApp.Services // BLL Layer - Reference to Repository, Models
MyApp.Services.Cache // Cached BLL Layer(Extremely recommended) - Reference to Services, Models
MyApp.UI.Web.WebForms // UI Layer - Reference to all of layers
I will try to do my best to explain with the example of basic implementation of 'Category' model.
-Infrastructure-
EntityBase.cs
BussinesRule.cs
IEntity.cs
IRepository.cs
-Models-
Categories(Folder)
Category.cs // Implements IEntity and derives from EntityBase
ICategoryRepository.cs // Implements IRepository
-Presenter-
Interfaces
IHomeView.cs // Put every property and methods you need.
ICategoryPresenter.cs
Implementations
CategoryPresenter.cs // Implements ICategoryPresenter
CategoryPresenter(IHomeView view, ICategorySevice categorySevice){
}
-Repository-
Repositories(Folder)
GenricRepository.cs // Implements IRepository
CategoryRepository : Implements ICategoryRepository and derives from GenricRepository
-Services-
Interfaces
ICategorySevice.cs
AddCategory(Category model);
Implementations
CategorySevice.cs // Implements ICategorySevice
CategorySevice(ICategoryRepository categoryRepository ){}
AddCategory(Category model){
// Do staff by ICategoryRepository implementation.
}
-Services.Cache-
// It all depents of your choose.. Radis or Web cache..
-UI.Web.WebForms-
Views - Home(Folder) // Implement a structure like in MVC views.
Index.aspx // Implements IHomeView
Page_Init(){
// Get instance of Presenter
var categoryPresenter = CategoryPresenter(this, new CategorySevice);
}
I'm not sure if i got your question correct, but maybe give you an idea:)

To Repository or Not To Repository

When I first learnt about Domain Driven Design, I was also introduced to the repository and unit of work patterns that once seemed to be top notch for the cool kids that threw SQL queries like cavemans against databases. The deeper I got into that topic, the more I learnt that they don't seem to be necessary anymore because of ORMs like EF and NHibernate that implement both unit of work and repositories into one API, called session or context.
Now I'm unsure what to do. To repository or not to repository. I really understand the argument that such leaky abstractions only over-complicate things while adding absolutely nothing that may simplify data access, however, it doesn't feel right to couple every possible aspect of my application to e.g. Entity Framework. Usually, I follow a few simple guidelines:
The domain layer is the heart of the system, containing entities, services, repositories...
The infrastructure layer provides implementations of domain interfaces of a infrastructural concern, e.g. file, database, protocols..
The application layer hosts a composition root that wire things up and orchestrates everything.
My solutions usually look like this:
Domain.Module1
Domain.Module2
IModule2Repo
IModule2Service
Module2
Infrastructure.Persistence
Repositories
EntityFrameworkRepositoryBase
MyApp
Boostrapper
-> inject EntityFrameworkRepositoryBase into IRepository etc.
I keep my domain layer clean by using a IRepository<'T> which is also a domain concern not depending on anything else that tells me how to access data. When I now would make a concrete implementation of IModule2Service that requires data access, I would have to inject DbContext and by this, coupling it directly to the infrastructure layer.
(Coming to Visual Studio project, this can end up really tricky because of circular dependencies!)
Additionally What can be an alternative to depositories and fucktons of works? CQRS? How does one abstract a pure infrastructural framework?
"Depository" lol....
Anyways, you got right the bit that you don't want the domain coupled to EF that's why the T in your repository interface should be domain aggregate root and NOT an EF entity (or a 'domain' object designed to work properly with EF).
Your Domain layer is never coupled to persistence because it only knows about abstractions. When Module2Service needs data access it either uses a DAO (or a repository - not necessarily the DDD version - if it makes sense) or the service itself is an implemented in DAL (if it doesn't contain business logic).
In your case probably the best approach is the DAO/repository which of course will 'hide' the EF part. If it seems you're writing too much code, you really aren't and I think it matters the most to keep the proper separations of concerns than saving 50 LoC (a whole 5-10 minutes).
CQRS is always good idea with a rich domain but as any solution it comes to the drawback that it requires more code (and I understand that every coder is lazy by definition, but we are required to do a 'fuckton' of work, an app doesn't build itself, a maintainable app is even more work at the beginning).
If by abstracting a pure infrastructural framework you mean hiding EF, the repository is your best bet and you don't even have to name the class 'repository', it's the principle that matters and that's what the repo does: abstracts persistence for the Domain.

How to avoid circular dependency: DAL.DbContext.DbSet<BLL.Model>

If DbContext is in the DAL then the generic type arguments of the DbSets cannot be the BLL classes (domain model). What are the best practice ways to separate these layers? An extra model in the DAL? Interfaces?
If you're doing DDD, I believe the repository (at least the interface for it) is part of your business / domain layer. Your implementation of the repository will be a separate assembly which would have to reference that business / domain layer. So your DAL knows about your business objects, but not the other way around. To do dependency injection, you'll probably have in your DAL layer something that configures your container to use Repository for your IRepository interface. If you need a unit of work patter, your interface would likely have to be part of the business layer as well. Again your implementation will be in your DAL and the DAL would configure the DI container appropriately. This is actually one of the things I dislike about the repository pattern, as you either need to ensure your users of your interface correctly manage the IUnitOfWork, or you need something to wrap the repository which does so.
In a traditional n-layer architecture, things are a bit different. In that case your business layer can talk to the DAL, and I've normally built the DAL to have DTOs which represent a row of data in the database. The business layer will then use these DTOs to hydrate the business objects (or if you're using something like CSLA.Net, the business objects know how to hydrate themselves).
Either way there shouldn't be a situation where you end up with a circular reference.
I usually consider the domain model as a separate layer.
If we look at the classic MVC paradaigm, then the model is used by both the View and the Controller.
No reason why it shouldn't be used by the DAL as well.
The Model, however, will not reference the DAL; all operations against the data store will be done by the controller.
So the general flow of things would be-
user interacts with the View
View invokes a method on the Controller
Controller uses the DAL to retrieve Model objects
Controller invokes methods on Model objects, saves them (using DAL) if necessary, and returns an answer to the View
Your BLL or Domain Layer should not worry about data access technical details, BLL shold be technology independent. If you want to stick with Entity framework you should generate POCO entities and move them to seperate layer, this way you can avoid circualr references.

Repository Pattern with 2 services & 2 dataccess layers - C# DDD?

Can anyone help, I have 2 applications and they are nearly identical. they have a completely different presentation layer (web) and the business logic and database are nearly identical. Basically one app has some things that the other doesn't.
so i was wondering if i can do the following without breaking any rules etc
Each app has their own presentation layer.
Each app has their own service layer.
Each app has their own data access layer.
Each app shares another service layer.
Hence the shared service layer both apps can access as the business logic is identical, but they both have another service layer which has 5 or 6 methods in there which are specific to that actual app
The data access layer - I don't see anyway of sharing this as there are 2 different db's with entity framework hence its got the EDM in there so its not dynamic - and the tables differ slightly.
I could use IOC on the shared data access layer I suppose
Would anyone help or comment weather this is good practise.. What I didn't want to do is have only a separate service layer when a lot of it is shared..
Is this a good idea? Maybe i have got it wrong, is there a better way?
As Arjen de Blok said, your business entities should use a repository, a repository is an object with methods to query, update or insert domain entities.
The interface which describes your repository belongs to your domain layer, but the implementation belongs to the infrastructure layer (DAL).
You can share the domain and infrastructure libraries between your two projects. If these two projects should retrieves their data through a shared web service or a shared database, you just have to choose (i.e inject) the correct implementation of your repository (your domain objects know only about the interface of your repository, not about the concrete type)
If the business logic is mostly identical then you should focus to this first.
If you want to do DDD then you should identify your entities and (business) services first and place these in a single library.
These entities and business services should talk to your infrastructure layer (your DAL).
If the infrastructure layer is very different in these two applications then try to work with interfaces. So wrap the intfrastructure layer with interfaces and only talk from the domain layer to your infrastructure layer via these interfaces.
To bind your business logic to your infrastructure's implementation you could use IoC/DI.
You could unify the DAL with a Repository interface. You could then implement the interface across projects. You will probably end up with a EF Repository base class as well. You could apply a similar technique to the services, leverage a common interface and then specialize the service implementations.

Categories