What are good ways to reduce the number of dependencies? - dependency-injection

I am using dependency injection for quite some time and I really like the technique, but I often have a problem of too many dependencies that should be injected 4 - 5 which seems to much.
But I cannot find a way to make it simpler. For instance I have a class with some business logic that sends messages, it accepts two other business logic dependencies to do what is needed (one to translate data to messages sent, and one to translate messages that are received).
But apart from this it needs some "technical" dependencies like ILogger, ITimerFactory (because it needs to create timers inside), IKeyGenerator (to generate unique keys).
So the whole list grows pretty big. Are there any good common ways to reduce the number of dependencies?

One way to handle those is to refactor towards Aggregates (or Facades). Mark Seemann wrote a good article on it, check it out (actually I highly recommend his book as well, just saying).
So say you have the following (as taken from the article):
public OrderProcessor(IOrderValidator validator,
IOrderShipper shipper,
IAccountsReceivable receivable,
IRateExchange exchange,
IUserContext userContext)
You can refactor it to:
public OrderProcessor(IOrderValidator validator,
IOrderShipper shipper,
IOrderCollector collector)
Where OrderCollector is a facade (it wraps the previous 3 dependencies):
public OrderCollector(IAccountsReceivable receivable,
IRateExchange exchange,
IUserContext userContext)
I hope this helps.
EDIT
In terms of the cross-cutting concerns (logging and caching for example) and a strategy to handle them, here is a suggestion (that's what I usually do), say you have the following:
public interface IOrderService
{
void DoAwesome();
}
public class OrderService : IOrderService
{
public void DoAwesome()
{
// do your thing here ... no logging no nothing
}
}
Here I'd use the decorator pattern to create an OrderService that has logging enabled:
public class OrderServiceWithLogging : IOrderService
{
private readonly IOrderService _orderService;
private readonly ILogger _logger;
public OrderServiceWithLogging(IOrderService orderService, ILogger logger)
{
_orderService = orderService;
_logger = logger;
}
public void DoAwesome()
{
_orderService.DoAwesome();
_logger.Log("Awesome is done!");
}
}
It might look like a bit of overhead but IMHO, it's clean and testable.
Another way would be to go into Aspect Oriented Programming and look into concepts such as interception, where basically you intercept certain method calls and perform tasks as a result. Many DI frameworks (I wanna say all?) support interception, so that might be something that you prefer.

Related

ASP.NET 5 / Core 1 Dependency Injection: Bad design or bad documentation?

I'm reading through the ASP.NET 5 docs and was choking on the chapter of dependency injection.
I am recommended to write my controllers like so:
public class MyController: Controller
{
private readonly MyService _myService;
public MyController(MyService myService)
{
_myService = myService;
}
public IActionResult Index()
{
// use _myService
}
}
The short and direct version is discouraged:
public class MyController : Controller
{
public IActionResult Index()
{
var myService = (MyService)HttpContext.RequestServices.GetService(typeof(MyService));
}
}
The given reason is because allegedly the recommended version...
[...] yields classes that are easier to test (see Testing) and are more loosely coupled.
The linked testing chapter doesn't shed any light on this weird statement.
I didn't look at the sources, but I assume whatever constructs the controller is using HttpContext.RequestServices.GetService itself to deliver the dependency? Clearly a test can setup a different implementation for testing, and clearly that is the whole point of a DI framework, right?
The colossus (MyService)HttpContext.RequestServices.GetService(typeof(MyService)) is bad enough, but a small helper could fix that (was a simple Get<MyService>() really so hard?).
But that this excessive clutter is recommended for basically every controller and more is disturbing.
It's all the more puzzling as there already is a Microsoft DI framework with a proper usage, MEF:
public class MyController : Controller
{
[Import]
private MyService _myService;
public IActionResult Index()
{
// use _myService
}
}
Why not at least just take that one? What's going on here?
This isn't a ASP.NET Core specific solution. This is how just about every DI framework works. The most common approach is to have all the dependencies of a controller as constructor parameters. This makes it clear what services the controller uses. There are multiple alternative solutions, but the basic idea stays the same and there are multiple pros and cons to them.
Clearly a test can setup a different implementation for testing, and clearly that is the whole point of a DI framework, right?
This line isn't clear to me. What do you think the 'whole point of a DI framework ' is? This line suggest you only use it so you can use a different implementation for testing.
But that this excessive clutter is recommended for basically every controller and more is disturbing.
Excessive clutter? What if I want to use MyService in two (or more) functions? Should I use this:
public class MyController : Controller
{
public IActionResult Index()
{
var myService = (MyService)HttpContext.RequestServices.GetService(typeof(MyService));
}
public IActionResult Index2()
{
var myService = (MyService)HttpContext.RequestServices.GetService(typeof(MyService));
}
}
Or should I opt for the solution where I set it up in the constructor? Seems like an obvious choice to me. In such a small example it may look like clutter, but add 10 lines of code to it and you'll barely notice a small constructor and some variable declarations.
You can use it while testing. It's a way to quickly grab something from the container when you need it, but it should certainly not be part of the actual code. You're simply hiding the dependency from sight.
At last you suggest property injection. This is a valid solution. But an often used argument against it is that it hides the dependency. If you define it as a parameter in the constructor you can't hide it. Besides, a lot of DI frameworks don't even have support for property or method injection because of this.
If you want to use MEF in your project you are free to do so. But it should, in my opinion, not be the default DI framework for ASP.NET. What's available right now is more than sufficient to do most tasks. If you need more functionality you can always use a different DI framework like StructureMap or AutoFac.
In the end it all comes down to what works for you. But stating this is either bad design or bad documentation is just wrong. You are of course free to prove me wrong on this. You could improve the ASP.NET documentation and/or would prove that the concept of inversion of control is wrong and suggest a better solution.

Why pass a parameters of multiple services to mvc controller?

I'm new to asp.net mvc world mostly a windows developer moving to web. Be nice...
I found ridiculous when I look at many examples of asp.net mvc web applications that the pass to their controllers a list of services
Like this
public CustomerController(ICustomerService customerService,
IAnotherService anotherService,
IYetAnotherService yetAnotherService,
IYetAgainAnotherService yetAgainAnotherService,
etc...
Would not be better to do something like
public CustomerController(IServices services)
{
}
public interface IServices
{
ICustomerService CustomerService{get;set;}
IAnotherServiceService AnotherService{get;set;}
IYetAnotherServiceService YetAnotherServiceService{get;set;}
}
Am I missing the obvious?
As anybody implemented the way I suggest in mvc4 or mvc5. I know mvc6 does it.
But I cannot use mvc6 at work.
Any samples using DI?
Thanks
What you're missing here is the fact that constructors with many parameters is a code smell often caused by that class having to many responsibilities: it violates the Single Responsibility Principle.
So instead of packaging the services to inject into a 'container' class that allows those services to be accessible using a public property, consider the following refactorings:
Divide the class into multiple smaller classes.
Extract logic that implements cross-cutting concerns (such as logging, audit trailing, validation, etc, etc)out of the class and apply those cross-cutting concerns using decorators, global filters (MVC) or message handlers (Web API). A great pattern for your business logic is the command/handler pattern.
Extract logic that uses multiple dependencies out of the class and hide that logic behind a new abstraction that does not expose the wrapped dependencies. This newly created abstraction is called an Aggregate Service.
I agree that for readability sake, even if you have multiple existing services which are also used in other applications, you could always wrap them in another class to avoid passing a long list of dependencies to the controllers.
When you have code in the API controllers that look like this:
public CustomerController(ICustomerService customerService,
IAnotherService anotherService,
IYetAnotherService yetAnotherService,
IYetAgainAnotherService yetAgainAnotherService,
...
That can be a code-smell and is an opportunity to refactor. But this does not mean the original code was a bad design. What I mean is in the API layer, we try not to clutter it with too many services that the controller is dependent on. Instead you can create a facade service. So in your example above, you refactor it to look like this:
public CustomerController(IServices services)
{
}
public interface IServices
{
ICustomerService CustomerService{get;set;}
IAnotherServiceService AnotherService{get;set;}
IYetAnotherServiceService YetAnotherServiceService{get;set;}
}
Which is good and then you can move the IServices to your service/business layer. The concrete implementation of that in the service/business layer will look like this:
public class AConcreteService:IServices {
public AConcreteService(ICustomerService cs, IAnotherServiceService as, IYetAnotherServiceService yas)
{
...
}
public List<Customer> GetCustomers(){
return _cs.GetCustomers();
}
public List<string> GetAnotherServiceData(){
return _as.AnotherServiceData();
}
public List<string> GetYetAnotherServiceData(){
return _yas.YetAnotherServiceData();
}
...
So that code will end up looking like your original code when implemented directly in the controller but is now in the service/business layer. This time it will be easy to unit test in the service class and the API layer will look much cleaner.

Using DbContext and DbSet instead of implementing repositories and unit of work

I have seen plenty of articles about implementing repositories and a unit of work. I have also seen articles about how doing this is just adding extra complexity, because the DbContext is already using the repository and unit of work pattern.
I will be refactoring an application that pretty much has a repository for each entity, and would like to remove as much complexity as possible.
Can anyone explain/provide links to articles/blogs/etc that explain how to use the DbContext instead of my own repositories?
Rob Conery's a smart guy, but I have to disagree with him on this one. Command/Query method he suggests just removes the query logic from the action (which is something, but not much). There's still no true abstraction. And, the base controller method is not great either. While the method of data access (here, an ORM) is abstracted to just one place in your code, making for somewhat easier changes in the future, it does nothing to abstract the API for working with that data layer, so it almost becomes pointless. The only thing it really saves you from is having to put private readonly AppContext context = new AppContext(); at the top of every controller. You could perhaps combine the two, but then you're still looking at having to modify every one of those query classes if your data layer changes.
I think the chief problem here is that everyone is trying to achieve something different. Rob's suggested approaches are geared towards staying DRY. Personally, my goal in abstracting the data layer is for the easy ability to switch out data access methods at a later point. Perhaps that's because I've been burned in the past by choose some method of getting at data that ended up not working out ideally in the long run. We can at least both agree, though, the traditional way of implementing repositories is a bad idea.
In truth, this is a problem with no true answer. To a certain extent you have to just do what works best for you and your application. The method I've settled on is somewhat akin to the repository pattern, I use generic methods instead of a generic class. Something like the following:
public class Repository : IRepository
{
protected readonly DbContext context;
public Repository(DbContext context)
{
this.context = context;
}
public IEnumerable<TEntity> GetAll<TEntity>()
{
var dbSet = context.Set<TEntity>;
return dbSet.ToList();
}
...
}
My actual class is much more complex than that, but that's enough to illustrate the main points. First, the context is injected. This is one area where I strongly disagree with Rob. Perhaps if you're playing fast and loose with your context you may not know "where it came from", but I use a dependency injection container which creates one instance per request of my context. In other words, I know exactly where it came from.
Second, because this is a standard old class with generic methods, I don't need to new up a bunch of them in my controller actions. I also don't have to define a separate repository class for each entity. I can simply inject this one dependency into my controller and roll:
public class FooController : Controller
{
private readonly IRepository repo;
public FooController(IRepository repo)
{
this.repo = repo;
}
...
}
Then, if I want to fetch some Foos, I just do:
repo.GetAll<Foo>();
Or if I want some Bars: repo.GetAll<Bar>().
Then, you can start to do really interesting things via generic constraints. Let's say I'd like to be able to pull out only items that are "published". All I need is an interface like:
public interface IPublishable
{
PublishStatus Status { get; }
DateTime? PublishDate { get; }
DateTime? ExpireDate { get; }
}
Then, I simply make whatever entities I want to be "publishable" implement this interface or inherit from an abstract class that implements it. Once that's all set up, I can now do something like the following in my repository:
public IEnumerable<TEntity> GetAllPublished<TEntity>()
where TEntity : IPublishable
{
var dbSet = context.Set<TEntity>();
return dbSet.Where(m =>
m.Status == PublishStatus.Published &&
m.PublishDate.HasValue && m.PublishDate.Value <= DateTime.Now &&
(!m.ExpireDate.HasValue || m.ExpireDate.Value > DateTime.Now)
).ToList();
}
Now, I have one method in one repository that can pull out just the published items for any entity that implements IPublishable. Code duplication is at a bare minimum, and more importantly, if I need to switch out the data access layer with something else like a differ ORM or even a Web API, I just have to change this one repository class. All the rest of my code happily chugs along as if nothing happened.

Dependency Injection + Ambient Context + Service Locator

Recently I was reading a lot of stuff about application design patterns: about DI, SL anti-pattern, AOP and much more. The reason for this - I want to come to a design compromise: loosely coupled, clean and easy to work with. DI seems ALMOST like a solution except one problem: cross-cutting and optional dependencies leading to constructor or property pollution. So I come with my own solution for this and I want to know what do you think of it.
Mark Seemann (the author of DI book and famous "SL is anti-patter" statement) in his book mentions a pattern called Ambient Context. Though he says he doesn't like it much, this pattern is still interesting: it's like old good singleton except it is scoped and provide default value so we don't have to check for null. It has one flaw - it doesn't and it can't know about it's scope and how to dispose itself.
So, why not to apply Service Locator here? It can solve problem of both scoping and disposing of an Ambient Context objects. Before you say it's anti-pattern: it is when you hide a contract. But in our case we hide OPTIONAL contract, so it's not so bad IMO.
Here some code to show what I mean:
public interface ILogger
{
void Log(String text);
}
public interface ISomeRepository
{
// skipped
}
public class NullLogger : ILogger
{
#region ILogger Members
public void Log(string text)
{
// do nothing
}
#endregion
}
public class LoggerContext
{
public static ILogger Current
{
get
{
if(ServiceLocator.Current == null)
{
return new NullLogger();
}
var instance = ServiceLocator.Current.GetInstance<ILogger>();
if (instance == null)
{
instance = new NullLogger();
}
return instance;
}
}
}
public class SomeService(ISomeRepository repository)
{
public void DoSomething()
{
LoggerContext.Current.Log("Log something");
}
}
Edit: I realize that asking not concrete question goes in conflict with stack overflow design. So I will mark as an answer a post best describing why this design is bad OR better giving a better solution (or maybe addition?). But do not suggest AOP, it's good, but it's not a solution when you really want to do something inside your code.
Edit 2: I added a check for ServiceLocator.Current is null. It's what I intent my code to do: to work with default settings when SL is not configured.
You can add cross-cutting concerns using hand-crafted decorators or some kind of interception (e.g. Castle DynamicProxy or Unity's interception extension).
So you don't have to inject ILogger into your core business classes at all.
A problem with an ambient context as the one you propose, is that it makes testing much harder. For a couple of reasons:
While running your unit tests, there must always be a valid instance registered in "ServiceLocator.Current". But not only that, it must be registered with a valid ILogger.
When you need to use a fake logger in a test (other than the simple
NullLogger), you will have to configure your container, since there
is no way in hooking into this, but since the container is a singleton, all other tests will use that same logger.
It will be non-trivial (and a waste of time) to create a solution that works when your unit tests are run in parallel (as MSTest does by default).
All these problems can be solved by simply injecting ILogger instances into services that need it, instead of using a Ambient Context.
And if many classes in your system depend on that ILogger abstraction, you should seriously ask your self whether you're logging too much.
Also note that dependencies should hardly ever be optional.

DDD and constructor explosion

I'm practicing DDD with ASP.NET MVC and come to a situation where my controllers have many dependencies on different services and repositories, and testing becomes very tedious.
In general, I have a service or repository for each aggregate root. Consider a page which will list a customer, along with it's orders and a dropdown of different packages and sellers. All of those types are aggregate roots. For this to work, I need a CustomerService, OrderService, PackageRepository and a UserRepository. Like this:
public class OrderController {
public OrderController(Customerservice customerService,
OrderService orderService, Repository<Package> packageRepository,
Repository<User> userRepository)
{
_customerService = customerService
..
}
}
Imagine the number of dependencies and constructor parameters required to render a more complex view.
Maybe I'm approaching my service layer wrong; I could have a CustomerService which takes care of all this, but my service constructor will then explode. I think I'm violating SRP too much.
I think I'm violating SRP too much.
Bingo.
I find that using a command processing layer makes my applications architecture cleaner and more consistent.
Basically, each service method becomes a command handler class (and the method parameters become a command class), and every query is also its own class.
This won't actually reduce your dependencies - your query will likely still require those same couple of services and repositories to provide the correct data; however, when using an IoC framework like Ninject or Spring it won't matter because they will inject what is needed up the whole chain - and testing should be much easier as a dependency on a specific query is easier to fill and test than a dependency on a service class with many marginally related methods.
Also, now the relationship between the Controller and its dependencies is clear, logic has been removed from the Controller, and the query and command classes are more focused on their individual responsibilities.
Yes, this does cause a bit of an explosion of classes and files. Employing proper Object Oriented Programming will tend to do that. But, frankly, what's easier to find/organize/manage - a function in a file of dozens of other semi-related functions or a single file in a directory of dozens of semi-related files. I think that latter hands down.
Code Better had a blog post recently that nearly matches my preferred way of organizing controllers and commands in an MVC app.
Well you can solve this issue easily by using the RenderAction. Just create separate controllers or introduce child actions in those controllers. Now in the main view call render actions with the required parameters. This will give you a nice composite view.
Why not have a service for this scenario to return a view model for you? That way you only have one dependency in the controller although your service may have the separate dependencies
the book dependency injection in .net suggests introducing "facade services" where you'd group related services together then inject the facade instead if you feel like you have too many constructor parameters.
Update: I finally had some available time, so I ended up finally creating an implementation for what I was talking about in my post below. My implementation is:
public class WindsorServiceFactory : IServiceFactory
{
protected IWindsorContainer _container;
public WindsorServiceFactory(IWindsorContainer windsorContainer)
{
_container = windsorContainer;
}
public ServiceType GetService<ServiceType>() where ServiceType : class
{
// Use windsor to resolve the service class. If the dependency can't be resolved throw an exception
try { return _container.Resolve<ServiceType>(); }
catch (ComponentNotFoundException) { throw new ServiceNotFoundException(typeof(ServiceType)); }
}
}
All that is needed now is to pass my IServiceFactory into my controller constructors, and I am now able to keep my constructors clean while still allowing easy (and flexible) unit tests. More details can be found at my blog blog if you are interested.
I have noticed the same issue creeping up in my MVC app, and your question got me thinking of how I want to handle this. As I'm using a command and query approach (where each action or query is a separate service class) my controllers are already getting out of hand, and will probably be even worse later on.
After thinking about this I think the route I am going to look at going is to create a SerivceFactory class, which would look like:
public class ServiceFactory
{
public ServiceFactory( UserService userService, CustomerService customerService, etc...)
{
// Code to set private service references here
}
public T GetService<T>(Type serviceType) where T : IService
{
// Determine if serviceType is a valid service type,
// and return the instantiated version of that service class
// otherwise throw error
}
}
Note that I wrote this up in Notepad++ off hand so I am pretty sure I got the generics part of the GetService method syntactically wrong , but that's the general idea. So then your controller will end up looking like this:
public class OrderController {
public OrderController(ServiceFactory factory) {
_factory = factory;
}
}
You would then have IoC instantiate your ServiceFactory instance, and everything should work as expected.
The good part about this is that if you realize that you have to use the ProductService class in your controller, you don't have to mess with controller's constructor at all, you only have to just call _factory.GetService() for your intended service in the action method.
Finally, this approach allows you to still mock services out (one of the big reasons for using IoC and passing them straight into the controller's constructor) by just creating a new ServiceFactory in your test code with the mocked services passed in (the rest left as null).
I think this will keep a good balance out the best world of flexibility and testability, and keeps service instantiation in one spot.
After typing this all out I'm actually excited to go home and implement this in my app :)

Resources