Dependency injection and many implementations of interface - c#

I have a small problem with using dependency injection in my project. To describe problem I will use simple example. Let's assume that I'm writing logger aplication and my end user is able to choose if log should be saved to file or written to the console. User control it by choosing checkboxes in running app. He can select both or only one. After selecting he clicks button "LOG" to perform action.
Now what I understand from my knowledge of DI I should create interfaces :
public interface ILogger
{
void log();
}
And two implementations
public class ConsoleLogger : ILogger
{
public void log()
{
...
}
}
public class FileLogger : ILogger
{
public void log()
{
...
}
}
I know that I can register both implementations in for example unity container and get them in constructor by using table but then I can't identify which implementations is FileLogger and which is ConsoleLogger (In case when user select only one checkbox)
Second options is use service locator pattern to resolve implementations from ioc by name. I dont know if it is a good approach
In my real application I will have more options than two and there will be a lot of shared interfaces by each option.
Maybe better is use MEF ?
Application will be written in WPF + PRISM.

The way I usually do this is to make your class depend on an ILoggerFactory, which can create ILogger instances given a name.
The factory implementation, LoggerFactory, would hold the container's kernel and be able to resolve the component by name.
Notice how the factory interface only tells you that it can create objects - it doesn't give you any hint about any underlying kernel, or DI framework - the factory implementation is the one that knows about those details.
Something like this:
public class MyLoggingClass
{
private readonly ILoggerFactory _loggerFactorty;
public MyLoggingClass(ILoggerFactory factory)
{
_loggerFactorty = factory;
var fileLogger = _loggerFactorty.Create("fileLogger");
var consoleLogger = _loggerFactorty.Create("consoleLogger");
}
}
public class LoggerFactory : ILoggerFactory
{
public ILogger Create(string key)
{
return kernel.Resolve<ILogger>(key);
}
}
Frameworks like Castle Windsor even give you these factories for free: you don't even have to write its implementation.

Service locator pattern is an anti-pattern now and should not be used.
In your case, it's better to use Strategy design pattern because you're creating objects dynamically at runtime.
The differences between dependency injection and strategy pattern are subtle but there are. For more information:
Strategy Pattern vs Dependency Injection
What is the difference between Strategy pattern and Dependency Injection?
To create objects dynamically, you could use factory method design pattern or abstract factory.

I don't see the point of creating a custom factory if all you want is basic IOC functionality. If you're going to develop the application using WPF and Prism, a good approach is to use one of the supported IOC containers. I have used Unity a lot and really like it. Another supported version is the MEF (as you suggested).
Both of them allow you to resolve interfaces using names. It is not bad practice and gives a structured way of resolving the correct interface.
For using Prism with Unity or Mef, see here:
https://learn.microsoft.com/en-us/previous-versions/msp-n-p/gg430868(v=pandp.40)

Related

Should I use Dependency Injection when adding new records to a database via an ORM and if so how? C# [duplicate]

This question already has answers here:
Dependency Injection - use with Data Transfer Objects (DTOs)?
(3 answers)
Closed 6 years ago.
I have recently started a small project (C# .Net console application) and I'm trying to use dependency injection "properly" with Castle Windsor as my DI container.
I am not entirely new to dependency injection since I've been unit testing for some time. I feel I've been doing OK so far but have run into a scenario where I feel I must instantiate an object far from the composition root.
In my data access layer I am using the Entity Framework (6) to get data from my database. This is all hidden behind interfaces that are defined in my domain logic layer.
I need to add a new log record, here is an abridged and edited version of my code;
public class Logger:ILogger
{
private readonly IContext _context;
public Logger(IContext context)
{
_context = context;
}
public void Write(string message)
{
var log = new Log();
log.Message = message;
context.Logs.Add(Log);
context.Save();
}
}
Log implements the ILog interface;
public interface ILog
{
string Message { get; set; }
}
This is a solution I have used in the past because it is possible to unit test this code but I am no longer injecting all my dependencies.
I have considered method injection (i.e pass an ILog in with the message), but where would the class that is consuming this code get it's instance from? The same problem is true if I were to inject a factory, it takes the problem out of this class and moves it to another.
I suspect that the solution (if one is required) lies in how I set up the object lifetime of the instances of ILog.
In my real implementation I have a Controller class that takes an instance of ILogger. I can register concrete implementations for Controller, ILogger and IContext with my DI container and I can resolve an instance of Controller and run the application but at run-time I need an unknown number of Log instances.
How can I push the creation of Log instances back to my DI container? Is this something I should be trying to do?
In general - you shouldn't need a DI here. DI does not mean you can't use 'new' operator at all. Yes you can and domain classes are very good example where you would use it.
But if there is some complex scenario that you want to abstract creation on Log instances, you can always use factory pattern:
public interface ILogFactory
{
ILog Create();
}
public class DefaultLogFactory : ILogFactory
{
public ILog Create()
{
return new Log();
}
}
This factory is now injectable and exchangeable. But like I said, you probably don't need or want that.

Dependency Injection - How to inject implementation of interface using Simple Injector when the implementation uses Unity for DI

I have two separate projects... One project is using Simple Injector and the other Unity. From the simple injector project, I am attempting to register the interface/implementation of a class located within the project using Unity for its DI. I can successfully do this and gain access to the class but anything marked as a Unity [Dependency] within that class does not resolve. I can register those dependencies to the Simple Injector container but it loses it once crossing into the class using Unity.
Example:
Project1 (using Simple Injector)
public class StartUp {
var container = new Container();
container.RegisterSingleton(typeof(IGenericRepo<>), typeof(GenericRepo));
container.RegisterSingleton<IService, Service>();
//more code below etc...
}
public class TestController
{
private readonly IService service;
public TestController(IService service)
{
this.service = service;
}
public void TestMethod()
{
var test = service.GetEverything();
}
}
Project2 (using Unity)
public class Service : IService
{
[Dependency]
public IGenericRepo<ServiceObj> _serviceRepo { private get; set; }
public IQueryable<ServiceObj> GetEverything()
{
return _serviceRepo.Get();
}
}
With the example above, I can get to the GetEverything method within Project 2, but then the _serviceRepo dependecy is null. Is there a way for it to know to use the registered GenericRepo<> from Project1?
Is this possible to do?
Thank you!
Ryan
If I understand correctly Project 2 is some shared project which is used in other projects which use Unity for Dependency Injection. Unity uses property injection in this case by annoting the property with the DependencyAttribute.
Simple Injector is capable of doing property injection. Property injection however should only be used for optional dependencies. And as you're running into a NullReferenceException this dependency is not optional!
So you should move the IGenericRepo<ServiceObj> to the constructor of IService. This makes it clear to users of IService that it needs a repository to function correctly. This becomes especially useful when you would unittest IService as the constructor will in this case clearly communicates that it needs a repository.
By moving the dependency to the constructor Simple Injector will inject the repository correctly or throw an ActivationException if the configuration is not valid.
You can test, and I recommend doing this, by calling container.Verify() as you can read here: Verify the container’s configuration. This will make the application to fail fast.
If project 2 can't be refactored or for some other compelling reason constructor injection is not an option, Simple Injector does support property injection. It does however not support this out-of-the-box. One of the design principles of Simple Injector is to never fail silently and therefore only Explicit property injection is advised. This will gives the container the opportunity to use its Diagnostic Services and fail fast if the configuration is invalid.
As you can read in the referenced documentation, there are 2 ways of doing it property injection:
By registering an initializer with a call to
container.RegisterInitializer()
By implementing IPropertySelectionBehavior
Option 2 will let Simple Injector check the dependencies using the Diagnostics Services automatically. When verifying all 'initializers' are executed also, but the code in lambda isn't checked for lifestyles etc.
Simple Injector does not encourage its users to take a dependency on the container and it therefore does not contain any Atrributes which you can use out-of-the-box such as Unity has the DependencyAttribute.
So you have 2 options here:
Let project 1 also take a dependency on Unity (which it indirectly already has!, yuck) and create an implementation of IPropertySelectionBehavior to search for the Unity DependencyAttribute
Create your own custom Attribute in project 2 and annotate _serviceRepo which this custom attribute also.
The only difference between 1 and 2 is which attribute is searched for.
If you can't touch project 2, option 2 isn't possible. Implementing IPropertySelectionBehavior is straightforward:
// custom attribute only for option 1
public class ImportAttribute : Attribute { }
class UnityDependencyPropertySelectionBehavior : IPropertySelectionBehavior
{
public bool SelectProperty(Type type, PropertyInfo prop)
{
return prop.GetCustomAttributes(typeof(DependencyAttribute)).Any();
}
}
You can configure the container using this custom IPropertySelectionBehavior by:
container.Options.PropertySelectionBehavior =
new UnityDependencyPropertySelectionBehavior();
To summarize:
Move the dependency to the constructor as it is not a optional dependency. In other words use constructor injection!
If there are compelling reasons not to do this implement IPropertySelectionBehavior

Domain Driven Design - Singletons

It's a bad idea to create a singleton when we are using ddd?
I'm thinking of creating two of them, one for global settings (which are saved in the database) and the other for local settings (which are saved in the Windows Registry in my application windows forms).
If singletons in ddd is acceptable, where and when should I fill them with the stored values?
Singletons implemented as is (1) aren't acceptable in DDD based on your case(2) and even in any other modern software development paradigm. Note that DDD is more than a software architectural paradigm, but when I say that common singleton implementation isn't acceptable I'm talking about how to properly implement DDD in programming languages like C#.
For example, the following code sample is a possible simple implementation of singleton:
// Very simple singleton using a static field initializer
public class SimpleSingleton
{
private readonly static SimpleSingleton _instance = new SimpleSingleton();
public SimpleSingleton Instance => _instance;
}
They're not swappable, and this means that you can't inject them using dependency injection(3). That is, testing is harder to implement too (you should understand that a system that can't be tested or it's hard to test is a very bad idea).
What can be acceptable is using a dependency injection/inversion of control container that can define component implementations' life-style like Castle Windsor and others, which means that you can still use dependency injection and define that only a single instance will be created during the life of the application (i.e. you get an instance where you get an injected component implementation, but once one is created by the internal component factory, this is the one that's being injected during one application life-cycle).
At the end of the day, your system is designed to be agnostic about how component life-cycle works. It's defined by configuration. I would say that object life management is an aspect when your system is designed this way (see this Wikipedia article to learn more about aspect-oriented programming).
Delegating component life management to an aspect and define what kind of life will have your components is a great advantage: your code can work in many hosting environments and on each of them your code can work differently by configuration.
Think about an ASP.NET WebAPI. Maybe some components should be singletons during a single request, and each request should work with its own singleton. Same component used in another environment maybe shouldn't be a singleton, but just a transient object (i.e. each time you inject it, it's a completely new object). With common singleton implementations you won't get this flexibility.
Your requirement done right
There're many possible approaches to provide a good solution to your problem. I'll describe two of many possible solutions:
1. Instead of thinking about a global settings object, you should inject these settings as a class of settings into each component where you require these settings
For example:
public interface IDatabaseSettings
{
string Host { get; set; }
}
public class RegistryDatabaseSettings : IDatabaseSettings
{
// This property should get and set the setting from and
// against the Windows Registry. It's just a sample and dummy
// implementation
public string Host { get; set; }
}
public interface ISomeRepository
{
}
public class SomeRepositoryImpl : ISomeRepository
{
private readonly IDatabaseSettings _dbSettings;
// Inject IDatabaseSetttings as constructor's dependency
public SomeRepositoryImpl(IDatabaseSettings dbSettings)
{
_dbSettings = dbSettings;
}
public IDatabaseSettings DatabaseSettings => _dbSettings;
}
And using your favourite inversion of control/dependency injection container, you can define that IDatabaseSettings must be instantiated once per application cycle (i.e. singleton).
2. If settings are a cross-layer concern...
...maybe you can define a class called Settings where you define all settings as public properties and you inject a singleton instance into any component requiring it:
public interface IDatabaseSettings
{
string Host { get; set; }
}
public interface ISettings
{
IDatabaseSettings Database { get; }
}
public interface ISomeRepository
{
}
public class SomeRepositoryImpl : ISomeRepository
{
private readonly ISettings _settings;
// Inject Settings as constructor's dependency
public SomeRepositoryImpl(ISettings settings)
{
_settings = settings;
// Now you can access DatabaseSettings as follows:
// Settings.Database.Host
}
public ISettings Settings => _settings;
}
For me, the issue with this approach is you're going to inject settings to components that shouldn't access/write settings which are from other domains or they're just not desirable to be accessed everywhere. I'm talking about not breaking one of most important principles in object-oriented programming: encapsulation.
(1) When I talk about a singleton pattern implementation as is, I'm describing a common singleton pattern implementation where the whole singleton class implements the single object life instantiation/management.
(2) OP talks about a settings that should be stored in some database and in Windows Registry. It would be a bad idea not using dependency injection, because there would be no chance to unit test a component requiring the whole settings without also involving the database and Windows Registry. Setting fakes wouldn't be possible.
(3) Some inversion of control containers have support to configure components using custom factories, where you can define that an instance of some implementation can be taken from any custom source. For example, that factory can return SomeSingleton.Instance and get it injected as any regular component.

How to reduce amount of passing IUnityContainer object through constructors?

I have a big class hierarchy.
When my app starts, I initialize UnityContainer object and configure it.
After that I always passing it through constructors to another classes in hierarchy.
Something like this :
Unity container has these classes as Registrations: IClassA, IClassB, IClassC, IClassD
All concrete implementations of interfaces have constructor with IUnityContainer parameter.
For example,
public class ClassA : IClassA
{
public ClassA(IUnityContainer unityContainer)
{
}
}
So, every time when I'm creating a new instance of some class I must pass an object of IUnityContainer.
May I reduce amount of passing IUnityContainer object as constructor's parameter?
Maybe by using Dependency attribute ?
Yes, you should reduce it.
You should reduce it to 0.
Using DI container like this is a bad practice. Don't treat DI container as a magical super factory.
You should only use the container to make it easier to compose your application at the composition root: read this
Your code shouldn't be aware that it is composed with a DI container, container is just a technology while DI is a technic. You should be able to compose your application without a container too.
So, how you can reduce it? Like this:
public class ClassA : IClassA
{
public ClassA()
{
}
}
Then if your ClassA needs something (a dependency, an interface), then you should inject that via constructor for example.
public class ClassA : IClassA
{
private readonly IComponent _component;
public ClassA(IComponent component)
{
_component = component;
}
}
You can use another injection patterns too: property injection, method injection, ambient context.
If you use a container like in your question then you hide all the dependencies of the actual class. You can't figure out what that actual class needs to work because it will use the container to resolve something ad-hoc. It's completely againts dependency injection because you not inject dependencies, you just inject a generic factory (you can ask for anything) which is very dangerous and highly increases complexity for nothing.
I highly recommend this book: Dependency Injection in .NET - Mark Seemann
What you are doing is abusing the container as a ServiceLocator. This is considered an anti-pattern in modern application architecture.
Use proper Dependency Injection instead. Martin Fowler gives a good introduction on the pattern.
Mark Seemann wrote a very good book on the topic called Dependency Injection in .NET.
And as #PeterPorfy already pointed out the concept of Composition Roots is important. You register all dependencies with your container there and then kickoff by resolving the root object of your application or service there.
You never hand the container to a class outside that composition root!

IoC with static and dynamic dependencies

I'm trying to implement IoC in my app. I have this model:
interface IService;
interface IComponent;
class Service : IService
Service()
class Component : IComponent
Component(IService service, object runtimeValue) { }
At some point in my app I need to get a IComponent. My app uses a IoC container (Unity). I can register Service with the container but I can't do the same for Component b/c of its dependency runtimeValue. According to this I have to use a factory and inject that wherever I need to get a IComponent:
interface IComponentFactory
IComponent CreateComponent(object runtimeValue)
class ComponentProvider : IComponentProvider
ComponentProvider(IComponentFactory factory) { }
IComponent CreateAndCacheComponent(object runtimeValue) {
_component = factory.CreateComponent(runtimeValue)
return _component
}
// other methods
I must be able to register the factory with the container, so it must have only static dependencies. At the same time it must be able to provide a service instance of type IService required to create a component.
Here is the factory implementation. The only thing I could think of was to use a Func<> delegate as dependency:
class ComponentFactory : IComponentFactory
ComponentFactory(Func<IService> serviceFactoryDelegate)
IComponent CreateComponent(object runtimeValue) {
return new Component(serviceFactoryDelegate.Invoke(), runtimeValue)
}
... and register the delegate with the container as static factory, so that it calls back the container to resolve the service (I'm using Unity 1.2 on .net 2.0):
Container
.Configure<IStaticFactoryConfiguration>()
.RegisterFactory<Func<IService>>(container => (Func<IService>)container.Resolve<IService>)
Now I can use the container to resolve a ComponentProvider and get a component based on a runtime value:
// this happens inside CompositionRoot
provider = Container.Resovle<IComponentProvider>()
component = provider.CreateAndCacheComponent("the component")
Now I have some questions about this:
I'm not happy that the factory calls new Component(...). Isn't this poor man's DI?
Does the Hollywood principle still stand when using Func<IService> on factory's constructor? I mean, it ultimately calls container.Resolve<>... kind of like SL. The only difference is the code is in the container registration part of the app rather than inside the factory class.
Is there anything (else) wrong with this implementation, as far as DI and IoC are concerned?
It's a big step away from Poor Man's DI, but it would be nice if you didn't have to change this factory method every time a new dependency gets added to the Component's constructor.
This isn't a problem per se. Think of it like you're injecting an anonymous factory class. It can still be mocked for unit testing, and the bindings can be changed, so you're still getting the benefits of DI. But it is an added layer of abstraction which is probably not necessary. You can still avoid it in this case by injecting the IService directly into the factory, rather than a Func.
Typically when using dependency injection, you want to inject services rather than values. The fact that you're finding that you have to have both may indicate that you need to reconsider your class's API. For example, maybe you should be passing the value in to the methods on the class rather than the constructor. It's hard to say what the best approach would be without knowing more details.
No, it isn't. The whole purpose of a factory is to create an instance of a concrete class.
Basically, yes, but as I already asked in my comment, I don't see why this is necessary. You could inject an instance of IService directly
It's a bit more complicated than it needs to be. Why the double redirection IComponentProvider -> IComponentFactory? It looks like IComponentFactory doesn't add any benefit.
Implement ComponentProvider like this:
class ComponentProvider : IComponentProvider
{
ComponentProvider(IService service) { _service = service; }
IComponent CreateAndCacheComponent(object runtimeValue) {
_component = new Component(_service, runtimeValue);
return _component;
}
This would give you the following benefits:
You get rid of the unnecessary interface IComponentFactory along with the corresponding implementation.
No need to register a factory for IService
Generally speaking, how you implement this it depends on what you really need:
"runtimeValue" can be the same throughout the runtime, e.g. a connection string that is read from the settings. In that case, there would be no need for a factory / provider, you could simply new up the instance and register it with the container. Everyone who needs an IComponent requests one in the constructor instead of the provider.
You would only implement a factory and pass that as a dependency around if the "runtimeValue" really changes between calls to CreateAndCacheComponent.
To question 1: there is nothing wrong with calling new in the factory. You have isolated instantiation to one place in your application; you just made that one place the factory instead of the container.
If you ever needed to mock or change implementations, you would just mock or change the factory implementation, rather than the Component alone.

Categories

Resources