I have an MVC project which has two services an OrganisationService and an AgreementService, my problem is that some of the organisations belong to a group/parent structure, when this is the case I need to get all agreements that belong to any of the organisations within the group.
I already have a method in my OrganisationService that can return a list of all the ids for organisations within the structure:
IEnumerable<int> GetRelatedOrganisationIds(int id)
I could create a method in the AgreementService which accepts the result of this but then I would need to inject both services into my controller and call them in turn e.g.
GetAgreementsByOrganisationIdList(IEnumerable<int> organisationIdList)
Is it ok to inject the OrganisationService into the AgreementService so that it can do the work itself? For example the following method would call GetRelatedOrganisationIds internally:
GetAgreementsByOrganisationId(int id)
Another reason I would like to inject it into the AgreementService is that I would not need to remember to check if the organisation was in a group/parent relationship and look up the ids each time I wanted to get a list of agreements.
I also thought of creating an OrganisationGroupParentInformationProvider and injecting that into the AgreementService instead, I may have spent far too much time thinking about this one.... how would you do it?
Yes, it would be fine to inject one service into the constructor of another. However, you might want to consider creating an interface for OrganisationService and having your AgreementService depend upon that abstraction, instead.
Another approach would be to create a new service with dependencies on both AgreementService and OrganisationService, and have that new service carry out the responsibility. The new service would of course be injected into your controller.
For guidance, consider whether having it all under AgreementService would violate the Single Responsibility Principle and/or Interface Segregation Principle. If so, make a new service.
Is it ok to inject the OrganisationService into the AgreementService so that it can do the work itself?
That wouldn't be injecting it. That would be making it a dependency to it. Regardless, I would say the way you have it is a better architecture because it's more testable. By having the agreement service call the organizations service on its own it's certainly less testable because somewhere you're going to have to inject an instance of the organization service.
Related
I am trying to learn some concepts about DDD and the part of persisting Aggregates is confusing me a bit. I have read various answers on the topic on SO but none of them seem to answer my question.
Let's say I have an Aggregate root of Product. Now I do not want to inject the ProductRepository that will persist this aggregate root in the constructor of the Product class itself. Imagine me writting code like
var prod = new Product(Factory.CreateProductRepository(), name, costprice);
in the UI layer. If I do not want to inject my repository via dependency injection in the Aggregate Root, then the question is where should this code go? Should I create a class only for persisting this AR? Can anyone suggest what is the correct & recommended approach to solve this issue?
My concern is not which ORM to use or how to make this AR ORM friendly or easy to persist, my question is around the right use of repositories or any persistence class.
Application Services
You are right, the domain layer should know nothing about persistence. So injecting the repository into Product is indeed a bad idea.
The DDD concept you are looking for is called Application Service. An application service is not part of the domain layer, but lives in the service layer (sometimes called application layer). Application services represent a use case (as opposed to a domain concept) and have the following responsibilities:
Perform input validation
Enforce access control
Perform transaction control
The last point means that an application service will query a repository for an aggregate of a specific type (e.g. by ID), modify it by using one of its methods, and then pass it back to the repository for updating the DB.
Repository Ganularity
Concerning your second question
Should I create a class only for persisting this AR?
Yes, creating one repository per aggregate is a common approach. Often, standard repository operations like getById(), update(), delete(), etc. are extracted into a reusable class (either a base class or by aggregation).
You can also create additional repositories for non-domain information, e.g. statistical data. In these cases, make sure that you don't accidentally miss a domain concept, however.
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:)
I have the following interfaces in a WCF service:
IProductRepository
IFieldRepository
IFieldValueRepository
ICategoryRepository
I implement each of these in a separate project called DatabaseRepository, while Product, Field, FieldValue and Category all sit in a common library shared between the service and the repository project.
Products contain Fields, which in turn contain FieldValues. I don't like the idea of my service constructor having 4 repositories passed in, so I also have IGlobalRepository, which contains a property for each other repository. I instantiate my service by passing a concrete implementation of IGlobalRepository to the constructor, using Ninject conventions based binding to handle this for me when the service is hosted in IIS.
So on my web service GetProductsByCategory looks something like this:
private IGlobalRepository Repo { get; set; }
public IEnumerable<Product> GetProductsByCategory(int CategoryID){
return Repo.ProductRepository.GetByCategory(int CategoryID);
}
This is all well and good, except that products have fields, and fields have values. Does that mean that I need to pass concrete implementations of IFieldRepository and IFieldValueRepository to Repo.ProductRepository?
I'm sure someone will suggest that ProductRepository should also be responsible for fetching field data, but I have it in a separate repository so that I can fetch fields independent of the product they are attached to.
Before I stared adopting the repository pattern, I would simply call a static method on Field or FieldValue in order to get what I needed. Passing around repositories seems like a much less elegant way of working.
So now to my actual question:
Is a global repository a good idea? I realise this is partly subjective, but would love to hear the opinions of others, and more importantly, what is considered best practice for this kind of scenario.
I don't think a global repository is a good idea.
You should create the repository definition according to usage. So yeah, the product repo should return all required data and it has nothing to do with the FieldRepo or other repo.
The app is coupled only to the interface and one repository can implement multiple interfaces. Also, you can have diferent concrete repositories working with the same db. The point of the repo is not to have one repo for each entity, it's to provide an interface for the app to get what it needs from the presistence. How you structure the things INSIDE persistence, that's a different story.
So, at least as an expriment try redefining the repo interfaces to return directly the objects the app needs it, ignoring which is entity, which object is part of another and so on.
Then start implementing the concrete repos. Remember, you have as many models as the app needs. Only in trivial cases there's one model to rule'm all
For each concrete class I have a Manager class. This class has methods like GetAll(), GetById(), Save, etc.
I've made these manager classes a Singleton because I always need one instance, and I have the ability to cache results. For example, when I call GetAll() and the next time I need this method again, the manager don't have to go to the database, it can return the cached results.
Is this a good approach? Or is there a better alternative way?
What you call manager classes are really "repositories"
Repositories should only work at an aggregate root level, not one repository per class. E.g. if I have an Order class which has a collection of OrderItem, then an Order repository would exist that would have Get/GetAll methods - as the Order is the agg root in this case.
All repository classes would usually be singleton classes, where you can usually enforce this easily via an IOC container.
Overall, I would say your approach of one "repository" per entity is bad - stick to one repository per aggregate root instead.
Why not include them as part of the concrete class but static? Saves the need for two seperate classes.
It sounds like you are close to implementing the Repository pattern, but not quite all the way there. I'd suggest looking into it. I wouldn't make them Singletons -- it makes it too hard to mock them out for your unit tests so you end up adding back doors to defeat the Singleton for testing. A cache makes a nice Singleton object, but why not simply share the cache this way instead of multiplying Singletons?
For testing/mocking purposes, I would advise against using a Manager/Repository Singleton.
If you do want to cache results, then I would suggest delegating to a dedicated Cache class. Any static magic can be contained within the Cache class and your Manager/Repository's semantics can be kept clean.
From a Single Responsibility Principle point of view, I should be able to understand how a Manager/Repository works without having to understand your caching scheme.
I have a InventoryController that gets a IInventoryRepository inyected, however my needs have changed, and now one of the controllers methods also needs to use another 2 repositories, ILoansRepository (to see the get info about loaned inventory items) and another one, where some stats and extra info are found.
The way it works is that a ViewModelBuilder class that gets called from an ActionMethod in the InventoryController, that is the one that actually needs those. Currently I was passing the IInventoryRepository from the controller to the builder, but how should I do it now? Should I get the 3 repositories injected into the controller, and then pass them to the builder, just as I've been doing now? Or should I just do a IoC.GetInstance()? (although I think that is an anti-pattern isnt it?)
thanks!
In situations like these, the following guidelines come into play:
Too many dependencies is a smell that you violate the Single Responsibility Principle.
Don't have more than four dependencies. This is a relative guideline. I personally strive to have less; I get restless as soon as I add a third dependency (see the first item above), but can live with up to four. More than that and I have to refactor.
Don't take dependencies just to pass them on.
As far as I can tell, with three dependencies, you are still more or less within the safety zone when it comes to the number of dependencies, although you should start watching that particular design aspect more carefully.
However, as I understand your current implementation, you simply pass on the dependencies to a ViewModelBuilder (thus violating the third bullet). A slightly better option would be to define an abstraction of that (say, IViewModelBuilder) and inject that into the controller instead of all three repositories.
Under no circumstance should you resort to the Service Locator anti-pattern (IoC.GetInstance()).
To much responsibility for controller.
Maybe you should create a special service to handle that and that service should use those repositories (through IoC) auto-wired by constructor.
If your controller does too much work, split it into several ones.
If you inject 3 repositories just to create ViewModelBinder, don't: inject (I)ViewModelBinder instead. Let IoC container do its job and resolve the dependencies for you; moreover, this will simplify the architecture, the testing, etc.
Using ServiceLocator / GetInstance isn't always avoidable; sometimes you don't have "root" injection point like MVC controller factory and can't control object creation - for example, of model binders. So, I let my model binders (not builders) call GetInstance but I make my own "root": for example, they call GetInstance<IModelResolver>, not GetInstance<Entity>.