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>.
Related
I'm writing a C# ASP.NET MVC web application using SOLID principles.
I've written a ViewModelService, which depends on a AccountService and a RepositoryService, so I've injected those two services in the the ViewModelServer.
The PermissionService depends on the HttpContextBase in order to use GetOwinContext() to get an instance of the UserManager. The controller has an instance of HttpContextBase that needs to be used - so it seems like I have to inject the HttpContextBase instance into the ViewModelService which then injects it into the PermissionService.
So, in terms of code I have:
public ViewModelService
public CategoryRepository(ApplicationDbContext context, IPermissionService permissionservice)
public AccountService(HttpContextBase httpcontext, IPrincipal securityprincipal)
to instantiate the ViewModelService, I then do this:
new ViewModelService(
new CategoryRepository(
new ApplicationDbContext(),
new PermissionService(
new AccountService(HttpContext, Thread.CurrentPrincipal),
new UserPasswordRepository(new ApplicationDbContext()),
new ApplicationSettingsService())),
new PasswordRepository(
new ApplicationDbContext(),
new PermissionService(
new AccountService(HttpContext, Thread.CurrentPrincipal),
new UserPasswordRepository(new ApplicationDbContext()),
new ApplicationSettingsService())),
new ModelValidatorService());
Should a dependency be injected from that many "levels" up, or is there a better way?
There's a balance to be struck.
On the one hand, you have the school of thought which would insist that all dependencies must be exposed by the class to be "properly" injected. (This is the school of thought which considers something like a Service Locator to be an anti-pattern.) There's merit to this, but taken to an extreme you find yourself where you are now. Just the right kind of complexity in some composite models, which themselves have composite models, results in aggregate roots which need tons of dependencies injected solely to satisfy dependencies of deeper models.
Personally I find that this creates coupling in situations like this. Which is what DI is intended to resolve, not to create.
On the other hand, you have the school of thought which allows for a Service Locator approach, where models can internally invoke some common domain service to resolve a dependency for it. There's merit to this, but taken to an extreme you find that your dependencies are less known and there's a potential for runtime errors if any given dependency can't be resolved. (Basically, you can get errors at a higher level because consuming objects never knew that consumed objects needed something which wasn't provided.)
Personally I've used a service locator approach a lot (mostly because it's a very handy pattern for introducing DI to a legacy domain as part of a larger refactoring exercise, which is a lot of what I do professionally) and have never run into such issues.
There's yin and yang either way. And I think each solution space has its own balance. If you're finding that direct injection is making the system difficult to maintain, it may be worth investigating service location. Conversely, it may also be worth investigating if the overall domain model itself is inherently coupled and this DI issue is simply a symptom of that coupling and not the cause of it.
Yes, the entire intent of Dependency Injection is that you compose big object graphs up-front. You compose object graphs from the Composition Root, which is a place in your application that has the Single Responsibility of composing object graphs. That's not any particular Controller, but a separate class that composes Controllers with their dependencies.
The Composition Root must have access to all types it needs to compose, unless you want to get into late-binding strategies (which I'll generally advise against, unless there's a specific need).
I am firmly of the opinion that Service Locators are worse than Dependency Injection. They can be a useful legacy technique, and a useful stepping stone on to something better, but if you are designing something new, then steer clear.
The main reason for this is that Service Locators lead to code that has implicit dependencies, and this makes the code less clear and breaks encapsulation. It can also lead to run time errors instead of compile time errors, and Interacting Tests.
Your example uses Constructor Injection, which is usually the most appropriate form of Dependency Injection:
public ViewModelService(ICategoryRepository categoryRepository, IPasswordRepository passwordRepository, IModelValidatorService modelValidator) { ... }
This has explicit dependencies, which is good. It means that you cannot create the object without passing in its dependencies, and if you try to you will get a compile time error rather than a run time one. It also is good for encapsulation, as just by looking at the interface of the class you know what dependencies it needs.
You could do this using service locators as below:
public ViewModelService()
{
var categoryRepository = CategoryRepositoryServiceLocator.Instance;
var passwordRepository = PasswordRepositoryServiceLocator.Instance;
var modelValidator FModelValidatorServiceLocator.Instance;
...
}
This has implicit dependencies, that you cannot tell just by looking at the interface, you must also look at the implementation (this breaks encapsulation). You can also forget to set up one of the Service Locators, which will lead to a run time exception.
In your example I thinky your ViewModelService is good. It references abstractions (ICategoryRepository etc) and doesn't care about how these abstractions are created. The code you use to create the ViewModelService is a bit ugly, and I would recommend using an Inversion of Control container (such as Castle Windsor, StructureMap etc) to help here.
In Castle Windsor, you could do something like the following:
container.Register(Classes.FromAssemblyNamed("Repositories").Pick().WithServiceAllInterfaces());
container.Register(Component.For<IAccountService>().ImplementedBy<AccountService>());
container.Register(Component.For<IApplicationDBContext>().ImplementedBy<IApplicationDBContext>());
container.Register(Component.For<IApplicationSettingsService>().ImplementedBy<IApplicationSettingsService>());
var viewModelService = _container.Resolve<ViewModelService>();
Make sure to read and understand the "Register, Resolve, Release" and "Composition Root" patterns before you start.
Good luck!
I've read a book "Dependency injection in .NET" by Mark Seemann and it opened my eyes on many things. But still few question left. Here is one of them:
Let's say we have a WCF service exposing API for working with some database:
public class MyService : IMyService
{
private ITableARepository _reposA;
private ITableARepository _reposB;
//....
public IEnumerable<EntityA> GetAEntities()
{
return _reposA.GetAll().Select(x=>x.ToDTO())
}
public IEnumerable<EntityB> GetBEntities()
{
return _reposB.GetAll().Select(x=>x.ToDTO())
}
//...
}
There may be dozens of repositories service depend on. Some methods use one, some methods another, some methods use few repositories.
And my question is how to correctly organize injection of repository dependencies into service?
Options I see:
Constructor injection. Create a huge constructor with dozens of arguments. Easy for usage, but hard for managing parameters list. Also it's extreemely bad for performance as each unused repository is a waste of resources even if it doesn't use separate DB connection.
Property injection. Optimizes performance, but usage becomes non-obvious. How should creator of the service know which properties to initialize for specific method call? Moreover this creator should be universal for each method call and be located in the composition root. So logic there becomes very complicated and error-prone.
Somewhat non-standard (not described in a book) approach: create a repository factory and depend on it instead of concrete repositories. But the book say factories are very often used incorrectly as a side way to overcome problems that can be resolved much better with proper DI usage. So this approach looks suspicious for me (while achieving both performance and transparency objectives).
Or is there a conceptual problem with this relation 1 to many dependencies?
I assume the answer should differ depending on service instance context mode (probably when it's Single instance, constructor injection is just fine; for PerCall option 3 looks best if to ignore the above warning; for perSession everything depends on the session lifetime: whether it's more close to Single instance or PerCall).
If it really depends on instance context mode, then it becomes hard to change it, because change requires large changes in the code (to move from constructor injection to property injection or to repository factory). But the whole concept of WCF service ensures it is simple to change the instance context mode (and it's not so unlikely that I will need to change it). That makes me even more confused about DI and WCF combination.
Could anyone explain how this case should be resolved correctly?
Create a huge constructor with dozens of arguments
You should not create classes with a huge number of constructor arguments. This is the constructor over-injection code-smell. Having constructors with a huge amount of arguments is an indication that such class does too much: violates the Single Responsibility Principle. This leads to code that is hard to maintain and extend.
Also it's extremely bad for performance as each unused repository is a waste of resources
Have you measured this? The amount of constructor arguments should be mainly irreverent for the performance of the application. This should not cause any noticeable difference in performance. And if it does, it becomes be time to look at the amount of work that your constructors do (since injection constructors should be simple) or its time to switch to a faster DI container if your constructors are simple. Creating a bunch of services classes should normally be blazingly fast.
even if it doesn't use separate DB connection.
The constructors should not open connections in the first place. Again: they should be simple.
Property injection. Optimizes performance
How should creator of the service know which properties to initialize for specific method call
The caller can't reliably determine which dependencies are required, since only constructor arguments are typically required. Requiring properties results in temporal coupling and you lose compile-time support.
Since the caller can't determine which properties are needed, all properties need to be injected and this makes the performance equivalent as with constructor injection, which -as I said- should not be a problem at all.
Somewhat non-standard (not described in a book) approach: create a repository factory and depend on it instead of concrete repositories.
Instead of injecting a repository factory, you could inject a repository provider, a pattern which is better known as the Unit of Work pattern. The unit of work may give access to repositories.
I assume the answer should differ depending on service instance context mode
No, since you should never use the WCF 'Single' mode. In most cases the dependencies you inject into your WCF services are not thread-safe and should not outlive a single request. Injecting them into a singleton WCF service causes Captive Dependencies and this is bad because it leads to all kinds of concurrency bugs.
The core problem here seems that your WCF Service classes are big and violate the Single Responsibily Principle, causing them to hard to create, maintain, and test. Fix this violation by either:
Splitting them up in multiple smaller classes, or
Moving functionality out of them into aggregate services and apply patterns such as the command/handler and query/handler patterns.
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.
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 understand one of the (maybe best) ways of using inversion of control is by injecting the dependent objects through the constructor (constructor injection).
However, if I make calls to these objects outside of the object using them, I feel like I am violating some sort of rule - is this the case? I don't think there is any way of preventing that from happening, but should I establish a rule that (outside of mocked objects) we should never call methods from these objects?
[EDIT] Here's a simplified example of what I am doing. I have a FileController object that basically is used for cataloging files. It uses a FileDal object that talks to the database to insert/query/update File and Directory tables.
On my real implementation I build the controller by instructing Castle to use a SQL Server version of the DAL, in my unit test I use an in-memory Sqlite version of the DAL. However, due to the way the DAL is implemented, I need to call BeginTransaction and Commit around the usage of the FileController so the connection does not get closed and I can later make retrievals and asserts. Why I have to do that is not much important, but it led me to think that calling methods on a DAL object that is used by other clients (controllers) didn't sound kosher. Here's an example:
FileDal fileDal = CastleFactory.CreateFileDal();
fileDal.BeginTransaction();
FileController fileController = new FileController(fileDal);
fileController.CallInterestingMethodThatUsesFileDal();
fileDal.Commit();
It really depends on the type of object - but in general, I'd expect that to be okay.
Indeed, quite often the same dependency will be injected into many objects. For example, if you had an IAuthenticator and several classes needed to use authentication, it would make sense to create a single instance and inject it into each of the dependent classes, assuming they needed the same configuration.
I typically find that my dependencies are immutable types which are naturally thread-safe. That's not always the case, of course - and in some cases (with some IoC containers, at least) you may have dependencies automatically constructed to live for a particular thread or session - but "service-like" dependencies should generally be okay to call from multiple places and threads.