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.
Related
In my current project my manager is forcing some design concept for dependency injection I would like to discuss because I’m curious what a specialists of dependency injection think about this approach. The ideas behind this is use of class called catalog that is implemented per each service (service in Service Fabric) and having all dependencies inside like this:
public interface IDepA
{
}
public interface IDepB
{
}
public interface IDepC
{
}
public class StandardConstructorInjectorService
{
private readonly IDepA _depA;
private readonly IDepB _depB;
private readonly IDepC _depC;
public StandardConstructorInjectorService(IDepA depA, IDepB depB, IDepC depC)
{
_depA = depA;
_depB = depB;
_depC = depC;
}
}
public class ServiceCatalog
{
private readonly Container _container;
public ServiceCatalog(Container container)
{
_container = container;
}
public IDepA DepA => _container.GetInstance<IDepA>();
public IDepB DepB => _container.GetInstance<IDepB>();
public IDepC DepC => _container.GetInstance<IDepC>();
}
public class ServiceWithCatalog
{
private readonly ServiceCatalog _catalog;
public ServiceWithCatalog(ServiceCatalog catalog)
{
_catalog = catalog;
}
}
From my perspective we have
Pros:
Code that is using catalog is simple
Dependencies can be used in Lazy mode so when code logic is not using them they will not be created – but on other hand I know that we should design classes in such way that they will use all dependencies
It is easy bootstrap those classes because they have one predefined catalog
Cons:
Dependencies to class is not directly visible
Smell for service locator but we use resolve only in catalog definition and not in business code so I’m not sure is this acceptable or maybe dependency injection police will hunt us down :)
What do you think about this approach?
Your ServiceCatalog class depends on the Container. This effectively makes this a Service Locator, which is an anti-pattern. The fact this this class is not 'business code' is irrelevant. The only thing that matters is that it is not part of the Composition Root, which makes this an anti-pattern.
Besides using an anti-pattern, the class exposes its dependencies, rather than hiding them, which is a bad idea as well. The main idea of this class is probably to group commonly used dependencies together, lowering the number of constructor dependencies a class has. Problem with this, however, is that it doesn't lower the complexity of a consuming class, but simply obscures the fact that a class has too many dependencies. A class with too many dependencies likely violates the Single Responsibility Principle.
Instead of using this service catalog 'pattern', stick to using Constructor Injection. When a class gets too many constructor dependencies, a code-smell called Constructor Over-Injection, action should be taken. There are many solutions for this, such as Facade Services, Decorators or Domain Events. A Facade Service hides its dependencies rather than exposing them.
All this information, and much more, can be read in this book, by Mark Seemann and myself.
How do I register types which take another registered type as a parameter and also simple types (like an integer)?
public interface IDeviceManager
{
// implementation omitted.
}
public class DeviceManager : IDeviceManager
{
public DeviceManager(IDeviceConfigRepository configRepo, int cacheTimeout)
{
// implementation omitted
}
}
I do have a container registration for the IDeviceConfigRepository. That's ok. But how do I create an instance of DeviceManager with the configured dependency and passing along an integer of my choice in composition root?
I thought about creating a factory.
public class DeviceManagerFactory : IDeviceManagerFactory
{
private readonly Container _container;
public DeviceManagerFactory(Container container)
{
_container = container;
}
public DeviceManager Create(int minutes)
{
var configRepo = _container.GetInstance<IDeviceConfigurationRepository>();
return new DeviceManager(configRepo, minutes);
}
}
This is pretty simple.
However now I do not have a registration for DeviceManager which is the type I ultimately need. Should I change these dependencies to the factory instead?
public class ExampleClassUsingDeviceManager
{
private readonly DeviceManager _deviceManager;
public ExampleClassUsingDeviceManager(DeviceManager deviceManager, ...)
{
_deviceManage = deviceManager;
}
// actions...
}
For this to work and to avoid circular dependencies I would probably have to move the factory from the "application" project (as opposed to class libraries) where the composition root is to the project where the DeviceManager is implemented.
Is that OK? It would of course mean passing around the container.
Any other solutions to this?
EDIT
In the same project for other types I am using parameter objects to inject configuration into my object graph. This works OK since I only have one class instance per parameter object type. If I had to inject different parameter object instances (for example MongoDbRepositoryOptions) into different class instances (for example MongoDbRepository) I would have to use some kind of named registration - which SimpleInjector doesn't support. Even though I only have one integer the parameter object pattern would solve my problem. But I'm not too happy about this pattern knowing it will break as soon as I have multiple instances of the consuming class (i.e. MongoDbRepository).
Example:
MongoDbRepositoryOptions options = new MongoDbRepositoryOptions();
MongoDbRepositoryOptions.CollectionName = "config";
MongoDbRepositoryOptions.ConnectionString = "mongodb://localhost:27017";
MongoDbRepositoryOptions.DatabaseName = "dev";
container.RegisterSingleton<MongoDbRepositoryOptions>(options);
container.RegisterSingleton<IDeviceConfigurationRepository, MongoDbRepository>();
I am excited to hear how you deal best with configurations done at composition root.
Letting your DeviceManagerFactory depend on Container is okay, as long as that factory implementation is part of your Composition Root.
Another option is to inject the IDeviceConfigRepository into the DeviceManagerFactory, this way you can construct a DeviceManager without the need to access the container:
public class DeviceManagerFactory : IDeviceManagerFactory {
private readonly IDeviceConfigurationRepository _repository;
public DeviceManagerFactory(IDeviceConfigurationRepository repository) {
_repository = repository;
}
public DeviceManager Create(int minutes) {
return new DeviceManager(_repository, minutes);
}
}
However now I do not have a registration for DeviceManager which is the type I ultimately need. Should I change these dependencies to the factory instead?
In general I would say that factories are usually the wrong abstraction, since they complicate the consumer instead of simplifying them. So you should typically depend on the service abstraction itself (instead of depending on a factory abstraction that can produces service abstraction implementations), or you should inject some sort of proxy or mediator that completely hides the existence of the service abstraction from point of view of the consumer.
#DavidL points at my blog post about runtime data. I'm unsure though whether the cacheTimeout is runtime data, although you seem to be using it as such, since you are passing it in into the Create method of the factory. But we're missing some context here, to determine what's going on. My blog post still stands though, if it is runtime data, it's an anti-pattern and in that case you should
pass runtime data through method calls of the API
or
retrieve runtime data from specific abstractions that allow resolving runtime data.
UPDATE
In case the value you are using is an application constant, that is read through the configuration file, and doesn't change during lifetime of the application, it is perfectly fine to inject it through the constructor. In that case it is not a runtime value. There is also no need for a factory.
There are multiple ways to register this in Simple Injector, for instance you can use a delegate to register the DeviceManager class:
container.Register<DeviceManager>(() => new DeviceManager(
container.GetInstance<IDeviceConfigRepository>(),
cacheTimeout: 15));
Downside of this approach is that you lose the ability of Simple Injector to auto-wire the type for you, and you disable Simple Injector's ability to verify, diagnose and visualize the object graph for you. Sometimes this is fine, while other times it is not.
The problem here is that Simple Injector blocks the registration of primitive types (because they cause ambiguity) while not presenting you with a clean way to make the registration. We are considering (finally) adding such feature in v4, but that doesn't really address your current needs.
Simple Injector doesn't easily allow you to specify a primitive dependency, while letting the container auto-wire the rest. Simple Injector's IDependencyInjectionBehavior abstraction allows you to override the default behavior (which is to disallow doing this). This is described here, but I usually advice against doing this, because it is usually requires quite a lot of code.
There are basically two options here:
Abstract the specific logic that deals with this caching out of the class and wrap it in a new class. This class will have just the cacheTimeout as its dependency. This is of course only useful when there actually is logical to abstract and is usually only logical when you are injecting that primitive value into multiple consumers. For instance, instead of injecting a connectionstring into multiple classes, you're probably better of injecting an IConnectionFactory into those classes instead.
Wrap the cacheTimeout value into a complex data container specific for the consuming class. This enables you to register that type, since it resolves the ambiguity issue. In fact, this is what you yourself are already suggesting and I think this is a really good thing to do. Since those values are constant at runtime, it is fine to register that DTO as singleton, but make sure to make it immutable. When you give each consumer its own data object, you won't have to register multiple instances of those, since they are unique. Btw, although named registations aren't supported, you can make conditional or contextual registrations using RegisterConditional and there are other ways to achieve named registrations with Simple Injector, but again, I don't think you really need that here.
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)
Having used Windsor for quite some time, I'm a little surprised that I haven't come across this "design" issue sooner. I don't know how best to tackle it.
I have a class ConverterService that is used to perform data conversions. This is the interface (I've changed the parameters/return values to objects to simplify the sample):-
public interface IConverterService
{
object ConvertData(object sourceData);
}
The converter class needs some configuration settings, provided by an ISettingsProvider. The settings are used both in the constructor and the ConvertData() method. I therefore inject the ISettingsProvider into the constructor:-
public class ConverterService : IConverterService
{
private ISettingsProvider _settingsProvider;
public ConverterService(ISettingsProvider settingsProvider)
{
_settingsProvider = settingsProvider;
// Do some one-time initialisation using info from settingsProvider
// and store the results in class variables (not shown), used by ConvertData.
}
public object ConvertData(object sourceData)
{
// Do the conversion - also uses _settingsProvider,
// and other variables initialised in the constructor ..
}
}
Both the ConverterService and SettingsProvider are registered with Windsor in the usual way:-
container.Register(Component.For<IConverterService>().ImplementedBy<ConverterService>().LifeStyle.Singleton);
container.Register(Component.For<ISettingsProvider>().ImplementedBy<SettingsProvider>().LifeStyle.Singleton);
Any class that needs to use the converter gets an IConverterService injected via its constructor - standard stuff. This works fine, but I now need the ability for many different consumers to use the ConverterService with different settings providers (two or three at most).
I can't make ConverterService transient as I don't want the initialisation overhead each time. It feels like I need a separate instance of the ConverterService for each type of ISettingProvider, but I'm not sure if/how I can accomplish this using Windsor, or is a more fundamental refactoring needed?
And how would I register the different settings providers, all of which implement ISettingsProvider? More specifically how would Windsor resolve the correct one (bearing in mind that the ConverterService constructor is merely expecting an ISettingsProvider)?
Any suggestions as to how I should (re-)design the classes would be much appreciated.
Can you not use a naming convention for your instances and control them that way? So each instance of your IConverterService would have an associated name to indicate which configuration it was using.
This question features some information on using named components/instances.
Castle Windsor - How to map Named instance in constructor injection
I just started migrating my web application to fully use Windsor IOC. Here is a little problem I am encountering;
I have couple of static classes which I used to store some application level global values
EG (Simplified version of the class):
public static class SiteInfo
{
public static Language Language = (Language)byte.Parse(SiteInfo.Val("language"));
public static string Code = Site.Code;
public static string Name = Site.Name;
public static SiteCachedData CachedData { get; set; }
public static Site Site { get; set; }
public static void Init()
{
//Get site info from DB here
//I need to inject _SiteRepository here but I can't
//since I don't have access to the constructor
}
}
I am new to IOC and I understand static classes are advised to be prevented. What is the good practice to handle this situation? I am thinking of converting this to a singleton but I am not sure if that is my best bet.
This is one of the reasons why I like to avoid static classes --they are hard to inject or invert control. They usually have to know intimate details of several low level classes. Since they are static classes you can leave them because they are already available to all of the other classes and don't require injection.
One trick that I've done is to create a second class that delegates into the static class. You can then put an interface onto the new class and get into an IoC framework easier.
public static class StaticClass
{
public static object Method()
}
public class NonstaticClass : INewInterface
{
public object Method()
{
return StaticClass.Method();
}
}
The good part of this refactor is that you can go method by method and then determine new objects and interfaces as you go. Eventually you may be able to get rid of the original static class. You would also register the new classes as singleton instances so that only one instance exists at a time.
In the context of an IoC container, it's a bit ambiguous to say 'convert it to a singleton'. If you mean the singleton design pattern, you probably shouldn't do it that way, as there are better alternatives in the IoC world.
IoC containers perform two main roles: to resolve dependencies between components, and to manage the lifetime of components. A container manages the lifetime of its components by deciding when to create and destroy component instances.
For example, when you call container.Resolve<SiteInfo>(), the container has to decide whether to re-use an existing SiteInfo instance or create a new one. How does the container decide? Well, when you register SiteInfo with the container, you can tell the container how you would like it to behave. If you register it as a Singleton, the container will only create a SiteInfo instance on the first call to container.Resolve<SiteInfo>(); on subsequent calls, it re-uses the existing SiteInfo instance.
The advantage of this technique over the singleton pattern is flexibility. If you use the design pattern, your SiteInfo class will forever be a singleton (unless you refactor). By using the container to manage the lifetime, you can change your mind later and just change the container registration code. Consumers of the component don't need to (and shouldn't) care whether the container provides them with a new instance or re-uses an existing one - they just call container.Resolve().
I'm not familiar with Windsor (I use Autofac), but it looks like you have two ways of registering a component as a singleton (I'm sure someone will correct me if this is wrong):
container.AddComponentLifeStyle<SiteInfo>(LifestyleType.Singleton)
or,
container.Register( Component.For<SiteInfo>()
.LifeStyle.Singleton );
However, a word of warning. In your example, your SiteInfo class has a dependency on the _SiteRepository class. You will therefore also need to register a _SiteRepository instance as a singleton in the container, so that it is available when the container resolves the SiteInfo. This _SiteRepository instance will remain in memory for the lifetime of the container, i.e. for the lifetime of the Web application, because it's a singleton. If the repository keeps a DB connection open, therefore, that connection will remain open for the same lifetime.
For this sort of reason, an alternative lifestyle is per-web-request - in other words, the container will create a new instance of your SiteInfo class once per web request. The per-web-request lifestyle is discussed in another question.
You can register an single instanec of a class in your container, so it behaves like a singleton. The container gives you the same instance every time.