I'm getting StackoverflowException's in my implementation of the decorator pattern when using dependency injection. I think it is because I'm "missing" something from my understanding of DI/IoC.
For example, I currently have CustomerService and CustomerServiceLoggingDecorator. Both classes implement ICustomerService, and all the decorator class does is use an injected ICustomerService but adds some simple NLog logging so that I can use logging without affecting the code in CustomerService while also not breaking the single responsibility principle.
However the problem here is that because CustomerServiceLoggingDecorator implements ICustomerService, and it also needs an implementation of ICustomerService injected into it to work, Unity will keep trying to resolve it back to itself which causes an infinite loop until it overflows the stack.
These are my services:
public interface ICustomerService
{
IEnumerable<Customer> GetAllCustomers();
}
public class CustomerService : ICustomerService
{
private readonly IGenericRepository<Customer> _customerRepository;
public CustomerService(IGenericRepository<Customer> customerRepository)
{
if (customerRepository == null)
{
throw new ArgumentNullException(nameof(customerRepository));
}
_customerRepository = customerRepository;
}
public IEnumerable<Customer> GetAllCustomers()
{
return _customerRepository.SelectAll();
}
}
public class CustomerServiceLoggingDecorator : ICustomerService
{
private readonly ICustomerService _customerService;
private readonly ILogger _log = LogManager.GetCurrentClassLogger();
public CustomerServiceLoggingDecorator(ICustomerService customerService)
{
_customerService = customerService;
}
public IEnumerable<Customer> GetAllCustomers()
{
var stopwatch = Stopwatch.StartNew();
var result = _customerService.GetAllCustomers();
stopwatch.Stop();
_log.Trace("Querying for all customers took: {0}ms", stopwatch.Elapsed.TotalMilliseconds);
return result;
}
}
I currently have the registrations setup like this (This stub method was created by Unity.Mvc):
public static void RegisterTypes(IUnityContainer container)
{
// NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
// container.LoadConfiguration();
// TODO: Register your types here
// container.RegisterType<IProductRepository, ProductRepository>();
// Register the database context
container.RegisterType<DbContext, CustomerDbContext>();
// Register the repositories
container.RegisterType<IGenericRepository<Customer>, GenericRepository<Customer>>();
// Register the services
// Register logging decorators
// This way "works"*
container.RegisterType<ICustomerService, CustomerServiceLoggingDecorator>(
new InjectionConstructor(
new CustomerService(
new GenericRepository<Customer>(
new CustomerDbContext()))));
// This way seems more natural for DI but overflows the stack
container.RegisterType<ICustomerService, CustomerServiceLoggingDecorator>();
}
So now I'm not sure of the "proper" way of actually creating a decorator with dependency injection. I based my decorator on Mark Seemann's answer here. In his example, he is newing up several objects that get passed into the class. This is how my it "works"* snippet works. However, I think I have missed a fundamental step.
Why manually create new objects like this? Doesn't this negate the point of having the container doing the resolving for me? Or should I instead do contain.Resolve() (service locator) within this one method, to get all the dependencies injected still?
I'm slightly familiar with the "composition root" concept, which is where you are supposed to wire up these dependencies in one and only one place that then cascades down to the lower levels of the application. So is the Unity.Mvc generated RegisterTypes() the composition root of an ASP.NET MVC application? If so is it actually correct to be directly newing up objects here?
I was under the impression that generally with Unity you need to create the composition root yourself, however, Unity.Mvc is an exception to this in that it creates it's own composition root because it seems to be able to inject dependencies into controllers that have an interface such as ICustomerService in the constructor without me writing code to make it do that.
Question: I believe I'm missing a key piece of information, which is leading me to StackoverflowExceptions due to circular dependencies. How do I correctly implement my decorator class while still following dependency injection/inversion of control principles and conventions?
Second question: What about if I decided I only wanted to apply the logging decorator in certain circumstances? So if I had MyController1 that I wished to have a CustomerServiceLoggingDecorator dependency, but MyController2 only needs a normal CustomerService, how do I create two separate registrations? Because if I do:
container.RegisterType<ICustomerService, CustomerServiceLoggingDecorator>();
container.RegisterType<ICustomerService, CustomerService>();
Then one will be overwritten meaning that both controllers will either both have a decorator injected or a normal service injected. How do I allow for both?
Edit: This is not a duplicate question because I am having problems with circular dependencies and a lack of understanding of the correct DI approach for this. My question applies to a whole concept not just the decorator pattern like the linked question.
Preamble
Whenever you are having trouble with a DI Container (Unity or otherwise), ask yourself this: is using a DI Container worth the effort?
In most cases, the answer ought to be no. Use Pure DI instead. All your answers are trivial to answer with Pure DI.
Unity
If you must use Unity, perhaps the following will be of help. I haven't used Unity since 2011, so things may have changed since then, but looking up the issue in section 14.3.3 in my book, something like this might do the trick:
container.RegisterType<ICustomerService, CustomerService>("custSvc");
container.RegisterType<ICustomerService, CustomerServiceLoggingDecorator>(
new InjectionConstructor(
new ResolvedParameter<ICustomerService>("custSvc")));
Alternatively, you may also be able to do this:
container.RegisterType<ICustomerService, CustomerServiceLoggingDecorator>(
new InjectionConstructor(
new ResolvedParameter<CustomerService>()));
This alternative is easier to maintain because it does not rely on named services, but has the (potential) disadvantage that you can't resolve CustomerService through the ICustomerService interface. You probably shouldn't be doing that anyway, so it ought not to be an issue, so this is probably a better alternative.
Question: I believe I'm missing a key piece of information, which is leading me to StackoverflowExceptions due to circular dependencies. How do I correctly implement my decorator class while still following dependency injection/inversion of control principles and conventions?
As was already pointed out the best way to do this is with the following construct.
container.RegisterType<ICustomerService, CustomerServiceLoggingDecorator>(
new InjectionConstructor(new ResolvedParameter<CustomerService>()));
This allows you to specify how the parameters are resolved by type. You could also do it by name but by type is a cleaner implementation and allows for better checking during compile time as a change or mistype in a string will not be caught. Note that the only minute difference between this code part and the code offered by Mark Seemann is a correction in the spelling of InjectionConstructor. I will not elaborate on this part any more as there is nothing else to add that Mark Seemann has not already explained.
Second question: What about if I decided I only wanted to apply the logging decorator in certain circumstances? So if I had MyController1 that I wished to have a CustomerServiceLoggingDecorator dependency, but MyController2 only needs a normal CustomerService, how do I create two separate registrations?
You can do this using the way specified above using the Fluent notation OR using named dependency with a dependency override.
Fluent
This registers the controller with the container and specifies an overrload for that type in the constructor. I prefer this approach over the second but it just depends on where you want to specify the type.
container.RegisterType<MyController2>(
new InjectionConstructor(new ResolvedParameter<CustomerService>()));
Named dependency
You do this the exact same way, you register both of them like so.
container.RegisterType<ICustomerService, CustomerService>("plainService");
container.RegisterType<ICustomerService, CustomerServiceLoggingDecorator>(
new InjectionConstructor(new ResolvedParameter<CustomerService>()));
The difference here is that you use a named dependency instead for the other types that can be resolved using the same interface. This is because the interface needs to be resolved to exactly one concrete type every time a resolve is done by Unity so you can not have multiple unnamed registered types that are registered to the same interface. Now you can specify an override in your controller constructor using an attribute. My example is for a controller named MyController2 and I added the Dependency attribute with the name also specified above in the registration. So for this constructor a CustomerService type will be injected instead of the default CustomerServiceLoggingDecorator type. MyController1 will still use the default unnamed registration for ICustomerService which is type CustomerServiceLoggingDecorator.
public MyController2([Dependency("plainService")]ICustomerService service)
public MyController1(ICustomerService service)
There are also ways to do this when you manually resolve the type on the container itself, see Resolving Objects by Using Overrides. The problem here is that you need access to the container itself to do this which is not recommended. As an alternative you could create a wrapper around the container that you then inject into the Controller (or other type) and then retrieve a type that way with overrides. Again, this gets a bit messy and I would avoid it if possible.
Building upon Mark's second answer I'd look to registering the CustomerService with a InjectionFactory and only register it with the service type without it's interface like:
containter.RegisterType<CustomerService>(new InjectionFactory(
container => new CustomerService(containter.Resolve<IGenericRepository<Customer>>())));
This would then allow, as in Mark's answer, for you to register the logging object like:
containter.RegisterType<ICutomerService, CutomerServiceLoggingDecorator>(new InjectionConstructor(
new ResolvedParameter<CustomerService>()));
This is basically the same technique that I use whenever I require something to be lazily loaded as I don't want my objects to depend upon Lazy<IService> and by wrapping them in proxy allows me to only inject IService but have it resolved lazily through the proxy.
This will also allow you to pick and choose where either the logging object or the normal object is injected instead of requiring magic strings by simply resolving a CustomerService for your object instead of the ICustomerService.
For a logging CustomerService:
container.Resolve<ICustomerService>()
Or for a non-logging CustomerService:
container.Resolve<CustomerService>()
Related
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.
What is suggested practice regarding constructor injection with Unity?
What of next two examples is better practice from DI point of view? Is there better solution?
(These examples are simple illustrations)
public interface ICircle
{
double Radius{get;set;}
}
Container.RegisterType<ICircle, SmallCircle>("Small");
Container.RegisterType<ICircle, BigCircle>("Big");
public class Bike{
Public Bike([Dependency("Big") ICircle bigCircle, Dependency("Small") ICircle smallCircle) { }
}
Or this, more strongly typed solution...
public interface IBigCircle : ICircle
{
// **Empty interface**
}
Container.RegisterType<ICircle, SmallCircle>();
Container.RegisterType<IBigCircle, BigCircle>();
public class Bike{
Public Bike( IBigCircle bigCircle, ICircle smallCircle) { }
}
What worries me is that number of empty interfaces can grow over the time in this second solution.
IMO, the first code sample is better than the first because it is not cluttering the design with unnecessary interfaces (e.g. IBigCircle). However, both examples are not great. The problem with the first sample is that using the DependencyAttribute couples the container to the application which is something to avoid.
So if the two examples are not great than what is a better alternative?
Here are a few. The first alternative is to use an InjectionFactory to instantiate the required object:
IUnityContainer container = new UnityContainer();
container.RegisterType<ICircle, SmallCircle>("Small");
container.RegisterType<ICircle, BigCircle>("Big");
container.RegisterType<Bike>(new InjectionFactory(
c => new Bike(c.Resolve<ICircle>("Big"), c.Resolve<ICircle>("Small"))));
In the above example the container is used to resolve the "Big" and "Small" registered ICircle implementations. Also, because we use new Bike we get compile time checking of the constructor arguments.
Another similar approach is to use an InjectionConstructor to specify the objects to inject:
container.RegisterType<Bike>(new InjectionConstructor(
new ResolvedParameter<ICircle>("Big"),
new ResolvedParameter<ICircle>("Small")
));
The above tells Unity to use the Constructor with two ICircle Parameters and the ResolvedParameter indicates to resolve the specific ICircle by name.
Another approach you could use (but probably wouldn't be the first choice but is included here for completeness) is to specify what types are required at resolve time instead of registration time:
container.Resolve<Bike>(
new ParameterOverride("bigCircle", container.Resolve<ICircle>("Big")),
new ParameterOverride("smallCircle", container.Resolve<ICircle>("Small")));
The example carries some assumptions with it. For example, it's suggested from reading the interface names that IBigCircle would have a larger radius than ISmallCircle but that depends on the implementation, not on the name of the interface. The interfaces can't guarantee what their names imply. (Just like IEnumerable<string> bigList, IEnumerable<string> smallList can't really enforce which is bigger.)
If what matters is that one is bigger than the other you could just depend on two ICircles and determine at runtime which is bigger. Or you could have an IWheels interface consisting of two ICircles and use some sort of factory to create acceptable pairs of circles out of available implementations.
In the first approach, your classes know the name of the dependencies that would be injected into them. So this code:
[Dependency("Big")] ICircle bigCircle
Is not very much different from:
bigCircle = ServiceLocator.Locate<ICircle>("Big");
This is the service locator anti-pattern.
Your class is basically guiding the container to inject a dependency with a specific name. It is involved in the composition process. When doing proper dependency injection, classes should have a passive role only.
Your second approach is an attempt to solve this problem by introducing yet another interface that represents the same abstraction just to please the container. What happens if you have a decorator for ICircle, do you have to create a similar decorator for IBigCircle?
A better approach is to do dependency injection without a container. This is called Pure DI. See this article for a related discussion. Pure DI is specially useful when you have multiple implementations of a single interface (which is true in many applications).
This is my scenario:
I have an application like this:
I Use Ninject as my DI Container and I am working with WPF
1-There is ClassB which is injected into ClassA Which is Injected into 1stViewModel which is injected into 1stView
2- Again There is ClassR which is injected into ClassQ Wich is Injected into 2ndViewModel which is injected into 2ndView
3-And this happens for the 3rd and 4th window
Questions:
1- What can I do to Resolve the Classes when they are needed (when user clicks on 1st Button or 2nd) not in my composition root?
2- If I don't Inject my ViewModels into my Views and I want to make new instance of my ViewModel inside my View, obviously it needs a parameter which is IClassA for the 1st and IClassQ for the 2nd for example. How can I do it?
Use ninject.extensions.factory with that you can define ToFactory bindings for a given interface you define or you can inject a Lazy<T> in your constructor. More details see the wiki of the extension here https://github.com/ninject/ninject.extensions.factory/wiki
(Was an answer to a duplicate of this question)
+1 on Daniel's answer - it's 100% correct. Just one explication and an example.
Where it's appropriate (you want just in time creation and caching of a single dependency instance), Lazy is the best choice. Not bindings needed, you just need the extension to be present.
The obvious difference between Lazy<IFoo> and a Factory that creates IFoos is that you'll always have the same instance whereas a Factory'd purpose is to create fresh ones.
If you simply want a factory to create a Foo for you instead of using Func<IFoo>, you can use exactly the following:
interface IFooFactory
{
IFoo CreateFoo();
}
Bind<IFoo>().To<Foo>();
Bind<IFooFactory>().ToFactory();
The .ToFactory() bit does all the implementation behind the scenes (i.e. it creates interceptors and Castle Dynamic Proxy with a bodies that achieve the following:
class _SomethingAnonymous : IFooFactory
{
readonly IResolutionRoot _resolutionRoot;
public _SomethingAnonymous(IResolutionRoot resolutionRoot)
{
_resolutionRoot=resolutionRoot;
}
IFoo CreateFoo()
{
_resolutionRoot.Get<IFoo>();
}
}
and Binds IFooFactory to it.
Having this code not be concrete means that (if necessary as you develop your code) provides a variety of ways to move beyond basic creation with no parameters.
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.
I most commonly am tempted to use "bastard injection" in a few cases. When I have a "proper" dependency-injection constructor:
public class ThingMaker {
...
public ThingMaker(IThingSource source){
_source = source;
}
But then, for classes I am intending as public APIs (classes that other development teams will consume), I can never find a better option than to write a default "bastard" constructor with the most-likely needed dependency:
public ThingMaker() : this(new DefaultThingSource()) {}
...
}
The obvious drawback here is that this creates a static dependency on DefaultThingSource; ideally, there would be no such dependency, and the consumer would always inject whatever IThingSource they wanted. However, this is too hard to use; consumers want to new up a ThingMaker and get to work making Things, then months later inject something else when the need arises. This leaves just a few options in my opinion:
Omit the bastard constructor; force the consumer of ThingMaker to understand IThingSource, understand how ThingMaker interacts with IThingSource, find or write a concrete class, and then inject an instance in their constructor call.
Omit the bastard constructor and provide a separate factory, container, or other bootstrapping class/method; somehow make the consumer understand that they don't need to write their own IThingSource; force the consumer of ThingMaker to find and understand the factory or bootstrapper and use it.
Keep the bastard constructor, enabling the consumer to "new up" an object and run with it, and coping with the optional static dependency on DefaultThingSource.
Boy, #3 sure seems attractive. Is there another, better option? #1 or #2 just don't seem worth it.
As far as I understand, this question relates to how to expose a loosely coupled API with some appropriate defaults. In this case, you may have a good Local Default, in which case the dependency can be regarded as optional. One way to deal with optional dependencies is to use Property Injection instead of Constructor Injection - in fact, this is sort of the poster scenario for Property Injection.
However, the real danger of Bastard Injection is when the default is a Foreign Default, because that would mean that the default constructor drags along an undesirable coupling to the assembly implementing the default. As I understand this question, however, the intended default would originate in the same assembly, in which case I don't see any particular danger.
In any case you might also consider a Facade as described in one of my earlier answers: Dependency Inject (DI) "friendly" library
BTW, the terminology used here is based on the pattern language from my book.
My trade-off is a spin on #BrokenGlass:
1) Sole constructor is parameterized constructor
2) Use factory method to create a ThingMaker and pass in that default source.
public class ThingMaker {
public ThingMaker(IThingSource source){
_source = source;
}
public static ThingMaker CreateDefault() {
return new ThingMaker(new DefaultThingSource());
}
}
Obviously this doesn't eliminate your dependency, but it does make it clearer to me that this object has dependencies that a caller can deep dive into if they care to. You can make that factory method even more explicit if you like (CreateThingMakerWithDefaultThingSource) if that helps with understanding. I prefer this to overriding the IThingSource factory method since it continues to favor composition. You can also add a new factory method when the DefaultThingSource is obsoleted and have a clear way to find all the code using the DefaultThingSource and mark it to be upgraded.
You covered the possibilities in your question. Factory class elsewhere for convenience or some convenience within the class itself. The only other unattractive option would be reflection-based, hiding the dependency even further.
One alternative is to have a factory method CreateThingSource() in your ThingMaker class that creates the dependency for you.
For testing or if you do need another type of IThingSource you would then have to create a subclass of ThingMaker and override CreateThingSource() to return the concrete type you want. Obviously this approach only is worth it if you mainly need to be able to inject the dependency in for testing, but for most/all other purposes do not need another IThingSource
I vote for #3. You'll be making your life--and the lives of other developers--easier.
If you have to have a "default" dependency, also known as Poor Man’s Dependency Injection, then you have to initialize and "wire" the dependency somewhere.
I will keep the two constructors but have a factory just for the initialization.
public class ThingMaker
{
private IThingSource _source;
public ThingMaker(IThingSource source)
{
_source = source;
}
public ThingMaker() : this(ThingFactory.Current.CreateThingSource())
{
}
}
Now in the factory create the default instance and allow the method to be overrided:
public class ThingFactory
{
public virtual IThingSource CreateThingSource()
{
return new DefaultThingSource();
}
}
Update:
Why using two constructors:
Two constructors clearly show how the class is intended to be used. The parameter-less constructor states: just create an instance and the class will perform all of it's responsibilities. Now the second constructor states that the class depends of IThingSource and provides a way of using an implementation different than the default one.
Why using a factory:
1- Discipline: Creating new instances shouldn't be part of the responsibilities of this class, a factory class is more appropriate.
2- DRY: Imagine that in the same API other classes also depend on IThingSource and do the same. Override once the factory method returning IThingSource and all the classes in your API automatically start using the new instance.
I don't see a problem in coupling ThingMaker to a default implementation of IThingSource as long as this implementation makes sense to the API as a whole and also you provide ways to override this dependency for testing and extension purposes.
You are unhappy with the OO impurity of this dependency, but you don't really say what trouble it ultimately causes.
Is ThingMaker using DefaultThingSource in any way that does not conform to IThingSource? No.
Could there come a time where you would be forced to retire the parameterless constructor? Since you are able to provide a default implementation at this time, unlikely.
I think the biggest problem here is the choice of name, not whether to use the technique.
The examples usually related to this style of injection are often extremely simplisitic: "in the default constructor for class B, call an overloaded constructor with new A() and be on your way!"
The reality is that dependencies are often extremely complex to construct. For example, what if B needs a non-class dependency like a database connection or application setting? You then tie class B to the System.Configuration namespace, increasing its complexity and coupling while lowering its coherence, all to encode details which could simply be externalized by omitting the default constructor.
This style of injection communicates to the reader that you have recognized the benefits of decoupled design but are unwilling to commit to it. We all know that when someone sees that juicy, easy, low-friction default constructor, they are going to call it no matter how rigid it makes their program from that point on. They can't understand the structure of their program without reading the source code for that default constructor, which isn't an option when you just distribute the assemblies. You can document the conventions of connection string name and app settings key, but at that point the code doesn't stand on its own and you put the onus on the developer to hunt down the right incantation.
Optimizing code so those who write it can get by without understanding what they are saying is a siren song, an anti-pattern that ultimately leads to more time lost in unraveling the magic than time saved in initial effort. Either decouple or don't; keeping a foot in each pattern diminishes the focus of both.
For what it is worth, all the standard code I've seen in Java does it like this:
public class ThingMaker {
private IThingSource iThingSource;
public ThingMaker() {
iThingSource = createIThingSource();
}
public virtual IThingSource createIThingSource() {
return new DefaultThingSource();
}
}
Anybody who doesn't want a DefaultThingSource object can override createIThingSource. (If possible, the call to createIThingSource would be somewhere other than the constructor.) C# does not encourage overriding like Java does, and it might not be as obvious as it would be in Java that the users can and perhaps should provide their own IThingSource implementation. (Nor as obvious how to provide it.) My guess is that #3 is the way to go, but I thought I would mention this.
Just an idea - perhaps a bit more elegant but sadly doesn't get rid of the dependency:
remove the "bastard constructor"
in the standard constructor you make the source param default to null
then you check for source being null and if this is the case you assign it "new DefaultThingSource()" otherweise whatever the consumer injects
Have an internal factory (internal to your library) that maps the DefaultThingSource to IThingSource, which is called from the default constructor.
This allows you to "new up" the ThingMaker class without parameters or any knowledge of IThingSource and without a direct dependency on DefaultThingSource.
For truly public APIs, I generally handle this using a two-part approach:
Create a helper within the API to allow an API consumer to register "default" interface implementations from the API with their IoC container of choice.
If it is desirable to allow the API consumer to use the API without their own IoC container, host an optional container within the API that is populated the same "default" implementations.
The really tricky part here is deciding when to activate the container #2, and the best choice approach will depend heavily on your intended API consumers.
I support option #1, with one extension: make DefaultThingSource a public class. Your wording above implies that DefaultThingSource will be hidden from public consumers of the API, but as I understand your situation there's no reason not to expose the default. Furthermore, you can easily document the fact that outside of special circumstances, a new DefaultThingSource() can always be passed to the ThingMaker.