IoC, Dependency injection and constructor arguments - c#

I have a service that I want to be able to create according to the Inversion of Control principle so I have created an interface and a service class.
public interface IMyService
{
void DoSomeThing1();
void DoSomeThing2();
void DoSomeThing3();
string GetSomething();
}
public class MyService : IMyService
{
int _initialValue;
//...
public MyService(int initialValue)
{
_initialValue = initialValue;
}
public void DoSomeThing1()
{
//Do something with _initialValue
//...
}
public void DoSomeThing2()
{
//Do something with _initialValue
//...
}
public void DoSomeThing3()
{
//Do something with _initialValue
//...
}
public string GetSomething()
{
//Get something with _initialValue
//...
}
}
With for example Unity I can set up my IoC.
public static class MyServiceIoc
{
public static readonly IUnityContainer Container;
static ServiceIoc()
{
IUnityContainer container = new UnityContainer();
container.RegisterType<IMyService, MyService>();
Container = container;
}
}
The problem is the constructor parameter. I could use a ParameterOverride like
var service = MyServiceIoc.Container.Resolve<IMyService>(new ParameterOverrides
{
{"initialValue", 42}
});
But I don't want to use losely typed parameters. What if someone changes the constructor parameter name or adds one parameter? He won't be warned at comple-time and maybe no one will detect it but the end user. Maybe the programmer changes he IoC setup for the tests, but forgets it for the "release" usage, then not even a codebase with 100% code coverage will detect the run-time error.
One could add an Init-function to the interface and service, but then the user of the service have to understand that and remember to call the init function every time he gets an instance of the service. The service becomes less self explanetory and open for incorrect usage. I'ts best if methods are not dependent on which order they are called.
One way to make it a little safer would be to have a Create-function on the Ioc.
public static class MyServiceIoc
{
//...
public IMyService CreateService(int initialValue)
{
var service = Container.Resolve<IMyService>();
service.Init(initialValue);
}
}
But the concerns mentioned above still applies if you only look at the service and its interface.
Does anyone have an robust solution to this problem? How can I pass an initial value to my service in a safe way still using IoC?

A DI Container is reflection-based, and fundamentally weakly typed. The problem is much broader than with Primitive Dependencies - it's present everywhere.
As soon as you do something like the following, you've already lost compile-time safety:
IUnityContainer container = new UnityContainer();
container.RegisterType<IMyService, MyService>();
var service = container.Resolve<IMyService>(new ParameterOverrides
{
{"initialValue", 42}
});
The problem is that you can remove the second statement, and the code still compiles, but now it'll no longer work:
IUnityContainer container = new UnityContainer();
var service = container.Resolve<IMyService>(new ParameterOverrides
{
{"initialValue", 42}
});
Notice that the lack of compile-time safety has nothing to do with the Concrete Dependency, but with the fact that a DI Container is involved.
This isn't a Unity problem either; it applies to all DI Containers.
There are cases where a DI Container may make sense, but in most cases, Pure DI is a simpler and safer alternative:
IMyService service = new MyService(42);
Here, you'll get a compiler error if someone else changes the API while you're looking away. That's good: compiler errors give you more immediate feedback than run-time errors.
As an aside, when you pass in a Primitive Dependency and invisibly turn it into a Concrete Dependency, you make it more difficult for the client to understand what's going on.
I'd recommend designing it like this instead:
public class MyService : IMyService
{
AnotherClass _anotherObject;
// ...
public MyService(AnotherClass anotherObject)
{
_anotherObject = anotherObject;
}
// ...
}
This is still easy and type-safe to compose with Pure DI:
IMyService service = new MyService(new AnotherClass(42));

How can I pass an initial value to my service in a safe way still using IoC?
You can explicitly call a type's constructor while registering it in Unity using the IUnityContainer.RegisterInstance method:
container.RegisterInstance<IMyService>(new MyService(42));
This would give you the compile-time safety that you mention, but the cost is that it would be instantiated only once, and would be created immediately (as opposed to when it is first requested).
You could perhaps deal with this drawback by using one of the method overloads, which accepts a LifetimeManager class.

It depends on your use case, but in IoC container world it could look something like this:
public class MyService : IMyService
{
int _initialValue;
// ...
public MyService(IConfigurationService configurationService)
{
_initialValue = configurationService.GetInitialValueForMyService();
}
// ...
}
If your class with constructor parameters is outside your code (e.g. in 3rd party library), you can use an adapter.
public class AdaptedMyService : MyService
{
public AdaptedMyService(IConfigurationService configurationService)
: base(configurationService.GetInitialValueForMyService())
{
}
}
And then register adapted class in IoC container like this:
container.Register<IMyService, AdaptedMyService>();

Related

Service which creates multiple children with dependencies

If I want to have a service which creates multiple objects which have injectable dependencies how do I code that?
public class MyCreator : ICreator
{
private readonly IAdapter _adapter;
public MyCreator()
{
_adapter = adapter;
}
public List<MappedObjects> Map()
{
List<MappedObjects> mo = new List<MappedObjects>();
foreach (ObjectToMap otm in ObjectToMap)
{
mo.Add(new MappedObject(otm, InjectedDependency dep));
}
}
}
If I register MyCreator with DI, will it know how to provide InjectedDependency?
EDIT: InjectedDependency is not one instance which should be passed to each MappedObject. I want a new instance of InjectedDependency for each new MappedObject.
Perhaps that means I have to create some kind of Factory object which know's how to create instances of InjectedDependency. I cannot provide more code because I don't know how to articulate what I need in C#.
I'm using teh inbuilt DI with .NET Core 2.2.
You will indeed need a factory:
public class MyCreator : ICreator
{
private readonly IInjectedDependencyFactory _factory;
public MyCreator(IInjectedDependencyFactory factory)
{
_factory = factory;
}
public List<MappedObjects> Map()
{
return ObjectToMap.Select(otm => new MappedObject(otm, _factory.Create())).ToList();
}
}
Obviously, you will have to write the factory class and interface and register them with your DI container.
You could also inject the DI container itself, IServiceProvider to get your new services directly from the container, given that that already is a factory. However, many people might consider this a code smell and the Service Locator pattern (that's what it would be) is not held in high regard nowadays. Other people might consider it wasteful to implement a factory on top of a factory. I guess there is no right way, you will have to live with some people calling it wrong, no matter what you do.
To keep your code testable, you need to inject the implementation of InjectedDependency in your MyCreator constructor.

Castle Windsor Abstract Factory

I'm trying to understand how to use TypedFactoryFacility to create an abstract factory, and I have it working at a basic level, however I don't fully understand how to scale it with runtime dependencies
Suppose I have a service that needs to be created at runtime:
public interface IRuntimeService {
void DoThing();
}
with the following implementation
public class RuntimeService : IRuntimeService {
public void DoThing() {
// Do some work
}
}
To create my IRuntimeService, I've created an abstract factory
public interface IRuntimeServiceFactory {
IRuntimeService CreateService();
}
In my Castle installer, I'm using the TypedFactoryFacility to register my class and abstract factory.
public class TypeInstaller : IWindsorInstaller {
public void Install(IWindsorContainer container, IConfigurationStore store) {
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<IRuntimeService>().ImplementedBy<RuntimeService>());
container.Register(Component.For<IRuntimeServiceFactory>().AsFactory());
}
Then in my class that will be using the service, I can use the factory to create new service instances at runtime.
var myService = m_ServiceFactory.CreateService();
Everything above works perfectly, however I'm running into a problem when my RuntimeService class needs to be injected with a dependency chain itself that include runtime parameters.
To expand the example above, suppose I have a new runtime dependency
public interface IRuntimeDependency {
void DoWork();
}
implemented by a class that takes a runtime string value through the constructor
public class RuntimeDependency : IRuntimeDependency {
private readonly string m_Param;
public RuntimeDependency(string param) {
m_Param = param;
}
public void DoWork() {
// Do work involving the param
}
}
And the previously defined service class now needs a reference to the dependency
public class RuntimeService : IRuntimeService {
private readonly IRuntimeDependency m_Dep;
public RuntimeService(IRuntimeDependency dep) {
m_Dep = dep;
}
public void DoThing() {
// Do some work involving the dependency
m_Dep.DoWork();
}
}
How do I now I create instances of my service using the TypedFactoryFacility?
I would expect do just be able to change my factory method to look like
IRuntimeService CreateService(string param);
but Windsor throws an error 'Could not resolve non-optional dependency for parameter 'param' type 'System.String'.
Windsor knows how to create an IRuntimeDependency if I give it a string, and it knows how to create a IRuntimeService if I give it the dependency, so why can't it directly create a IRuntimeService with the string param?
I can make it work by having two distinct factory methods
IRuntimeService CreateService(IRuntimeDependency dep);
IRuntimeDependency CreateDependency(string param);
and creating the dependency, manually myself
var dep = m_ServiceFactory.CreateDependency(param);
var myService = m_ServiceFactory.CreateService(dep );
^^^This works, but the whole point of using a container is so that it will take care of assembling new objects for me. This is a relatively simple example involving only one dependency, but it would easily grow out of control with a more complex object graph.
I could of course create my own factory implementations, but that also nullifies the benefit of using the TypedFactoryFacility which is supposed to create the abstract factory implementations for you. I have a hard time believing there's not an existing solution to this problem but the Windsor examples don't contain any chained run-time dependencies.
I don't think using a FactoryComponentSelector is the correct approach because there's only one possible path to create the RuntimeService instance. It should be able to auto-resolve.
In many or most cases, an object resolved by the container depends on implementations of other interfaces which are also resolved by the container. So as long as all of the interfaces have registered implementations, the container can resolve the entire dependency chain.
But in this case RuntimeDependency depends on a string, which isn't something the container can resolve.
public RuntimeDependency(string param) {
m_Param = param;
}
In this case you can use the DependsOn method to explicitly provide a value to fulfill that dependency.
container.Register(Component.For<IRuntimeDependency, RuntimeDependency>()
.DependsOn(Dependency.OnValue("param","whatEverTheValueIs")));
That value can, of course, come from configuration or wherever else. I use this a lot with SQL connection strings.
It is possible using DynamicParameters.
container.Register(Component.For<IRuntimeService>()
.ImplementedBy<RuntimeService>()
.LifestyleTransient()
.DynamicParameters((k, d) => {
d["dep"] = new RuntimeDependency((string)d["param"]);
}));
Keep in mind that the dictionary keys have to match the parameter names in the CreateService method and RuntimeService constructor.
Edit: You should also make it LifestyleTransient if you intend to create a new instance each time the factory method is called. (The default is singleton)
It seems that what I am asking for is not possible by design.
See this other SO answer.
https://stackoverflow.com/a/3905496/2029835

How to avoid Service Locator Anti-Pattern?

I'm trying to remove a Service Locator from an abstract base class, but I'm not sure what to replace it with. Here is a psuedo-example of what I've got:
public abstract class MyController : Controller
{
protected IKernel kernel;
public MyController(IKernel kernel) { this.kernel = kernel); }
protected void DoActions(Type[] types)
{
MySpecialResolver resolver = new MySpecialResolver(kernel);
foreach(var type in types)
{
IMyServiceInterface instance = resolver.Get(type);
instance.DoAction();
}
}
}
The problem with this is that the instanciator of a derived class doesn't know what bindings the kernel must have in order to keep MySpecialResolver from throwing an exception.
This might be intrinsicly intractable because I don't know from here which types I'll have to resolve. The derived classes are responsible for creating the types parameter, but they aren't hardcoded anywhere. (The types are based on the presence of attributes deep within the derived class's composition hierarchy.)
I've trying to fix this with lazy loading delegates, but so far I haven't come up with a clean solution.
Update
There are really two issues here, one is that the IoC container is passed to the controller, acting as a service locator. This is easy to remove--you can move the location up or down the call stack using all sorts of techniques.
The second issue is the difficult one, how can you ensure that the controller has the necessary services when the requirements aren't exposed until runtime. It should have been obvious from the start: you can't! You will always be dependent upon either the state of the service locator or contents of a collection. In this particular case no amount of fiddling will ever resolve the problem described in this article with staticly typed dependencies. I think that what I'm going to end up doing is passing a Lazy array into the controller constructor and throwing an exception if a required dependency is missing.
I agree with #chrisichris and #Mark Seemann.
Ditch the kernel from the controller. I'd switch your resolver composition a little bit so that your controller can remove the dependency on the IoC container and allow the resolver to be the only item that worries about the IoC container.
Then I would let the resolver get passed into the constructor of the controller. This will allow your controller to be far more testable.
For example:
public interface IMyServiceResolver
{
List<IMyServiceInterface> Resolve(Type[] types);
}
public class NinjectMyServiceResolver : IMyServiceResolver
{
private IKernal container = null;
public NinjectMyServiceResolver(IKernal container)
{
this.container = container;
}
public List<IMyServiceInterface> Resolve(Type[] types)
{
List<IMyServiceInterface> services = new List<IMyServiceInterface>();
foreach(var type in types)
{
IMyServiceInterface instance = container.Get(type);
services.Add(instance);
}
return services;
}
}
public abstract class MyController : Controller
{
private IMyServiceResolver resolver = null;
public MyController(IMyServiceResolver resolver)
{
this.resolver = resolver;
}
protected void DoActions(Type[] types)
{
var services = resolver.Resolve(types);
foreach(var service in services)
{
service.DoAction();
}
}
}
Now your controller isn't coupled to a specific IoC container. Also your controller is much more testable since you can mock the resolvers and not require an IoC container at all for your tests.
Alternatively, if you don't get to control when a controller is instantiated, you can modify it slightly:
public abstract class MyController : Controller
{
private static IMyServiceResolver resolver = null;
public static InitializeResolver(IMyServiceResolver resolver)
{
MyController.resolver = resolver;
}
public MyController()
{
// Now we support a default constructor
// since maybe someone else is instantiating this type
// that we don't control.
}
protected void DoActions(Type[] types)
{
var services = resolver.Resolve(types);
foreach(var service in services)
{
service.DoAction();
}
}
}
You would then call this at your application start up to initialize the resolver:
MyController.InitializeResolver(new NinjectMyServiceResolver(kernal));
We did this to handle elements created in XAML who require dependencies resolved but we wanted to remove Service Locator like requests.
Please excuse any syntactical errors :)
I'm writing a blog post series on the topic of refactoring an MVVM application with Service Locator calls in the view models you might find interesting. Part 2 is coming soon :)
http://kellabyte.com/2011/07/24/refactoring-to-improve-maintainability-and-blendability-using-ioc-part-1-view-models/
Maybe you should just do away the Kernel, Types and MySpecialResolver and let the subclasses call DoActions with the IMyServiceInterface instances they need as argument directly. And let the subclasses decide how they get to these instances - they should know best (or in case they don't know which exactly the one who ever decides which instances of IMyServiceInterface are needed)
I would have liked to have a bit more information before posting this answer, but Kelly put me on the spot. :) Telling me to put my code where my mouth is, so to speak.
Like I said in my comment to Kelly, I disagree with moving the resolver/locator from a static implementation to an injected implementation. I agree with ChrisChris that the dependencies the derived type needs should be resolved in that class and not delegated to the base class.
That said, here is how I would remove the service location...
Create Command Interface
First of all I would create a command interface for the specific implementation. In this case the types sent with the DoActions method are generated from attributes, so I would create an IAttributeCommand. I am adding a Matches method to the command in order to declare the command for use by certain types.
public interface IAttributeCommand
{
bool Matches(Type type);
void Execute();
}
Add Command Implementations
To implement the interface, I pass in the specific dependencies I need to execute my command (to be resolved by my container). I add a predicate to my Matches method, and define my Execute behavior.
public class MyTypeAttributeCommand : IAttributeCommand
{
MyDependency dependency;
SomeOtherDependency otherDependency;
public MyTypeAttributeCommand (MyDependency dependency, ISomeOtherDependency otherDependency)
{
this.dependency = dependency;
this.otherDependency = otherDependency
}
public bool Matches(Type type)
{
return type==typeof(MyType)
}
public void Execute()
{
// do action using dependency/dependencies
}
}
Register Commands with Container
In StructureMap (use your favorite container), I would register the array like so:
Scan(s=>
{
s.AssembliesFromApplicationBaseDirectory();
s.AddAllTypesOf<IAttributeCommand>();
s.WithDefaultConventions();
}
Select and Execute Commands Based on Type
Finally, on the base class, I define an IAttributeCommand array in my constructor arguments to be injected by the IOC container. When the derived type passes in the types array, I will execute the correct command based on the predicate.
public abstract class MyController : Controller
{
protected IAttributeCommand[] commands;
public MyController(IAttributeCommand[] commands) { this.commands = commands); }
protected void DoActions(Type[] types)
{
foreach(var type in types)
{
var command = commands.FirstOrDefault(x=>x.Matches(type));
if (command==null) continue;
command.Execute();
}
}
}
If you multiple commands can handle one type, you can change the implementation: commands.Where(x=>x.Matches(type)).ToList().ForEach(Execute);
The effect is the same, but there is a subtle difference in how the class is constructed. The class has no coupling to an IOC container and there is no service location. The implementation is more testable as the class can be constructed with its real dependencies, with no need to wire up a container/resolver.

How to deal with scope-natured services like transactions in a DI and IOC environment

Suppose that your code is properly designed for DI and IOC through constructor injection of any dependencies. Then whether an IOC container or DI-by-hand is used or not at the composition root doesn't matter much for this problem. I think.
Anyway, I find myself over and over again in a mental struggle with how I should best deal with scope-based services, like transactions or other obviously transient operations. There are constraints that I want to abide to:
Don't let dependency interfaces be IDisposable - it's a leaky abstraction that only the actual implementing type (and the fiddler sitting at the composition root) should care about.
Don't use static service locator types deep down the graph to resolve a dependency - only inject and resolve through the constructor.
Don't pass the IOC container, if any, as a dependency down the graph.
To be able to use using, we need IDisposable, but since a dependency interface shouldn't be IDisposable, how do you get around it to get scoped behavior?
In cases like this I would inject a service factory that creates those scoped services and let the service interface derive from IDisposable. This way the factory would be responsible to create the appropriate service instances and the only point that decides which service implementation to return. You would not need to inject the scoped service anywhere.
public interface ITransaction : IDisposable
{
}
public interface ITransactionFactory
{
ITransaction CreateTransaction();
}
public class Foo
{
private readonly ITransactionFactory transactionFactory;
public Foo(ITransactionFactory transactionFactory)
{
this.transactionFactory = transactionFactory;
}
public void DoSomethingWithinTransaction()
{
using(ITransaction transaction = this.transactionFactory.CreateTransaction())
{
DoSomething();
}
}
}
Most IoC containers today have substantial built-in support for units of work of this nature.
In Autofac, the mechanism that best fits your requirements is the Owned<T> relationship type. You can see it in action (and get some more material) via this article.
Hope this helps,
Nick
Roll your own "garbage collector" maybe? Something that periodically checks IsComplete and/or an LastAccessed attribute of a Dictionary<Transaction> and wastes the "old" ones. It's "a walking memory leak" but either you clean-up explicitly (like through IDisposable) or you workout how to clean-up automatically.
There may be an AOP solution to kicking-off the "gc"... a commit/rollback sounds like a good place to cut... and maybe you won't even need a GC at all... just cleanup the transaction on the way back-up the callstack from commit or rollback.
Good luck with it. I'll be interested to see what solutions (and ideas) other people come-up with.
Cheers. Keith.
I guess another alternative you could use is to wrap your instances with a disposable type, that way it could automatically handle the disposal of the type regardless of whether the type is actually disposable. E.g, I could define something like:
public class DisposableWrapper<T> : IDisposable
{
private readonly T _instance;
private readonly IDisposable _disposable;
public DisposableWrapper(T instance)
{
_instance = instance;
_disposable = instance as IDisposable;
}
public void Dispose()
{
if (_disposable != null)
_disposable.Dispose();
}
public static implicit operator T(DisposableWrapper<T> disposableWrapper)
{
return disposableWrapper._instance;
}
}
(Hopefully with a bit more error handling!)
Given that I know at the point of disposal whether the type is disposable, I can call it accordingly. I can also provide an implicit operator to cast back to the inner type from it. With the above, and a nifty extension method:
public static class DisposableExtensions
{
public static DisposableWrapper<T> Wrap<T>(this T instance)
{
return new DisposableWrapper<T>(instance);
}
}
Let's imagine that I have a service I am injecting into a type, it could be:
public interface IUserService
{
IUser GetUser();
}
I could potentially do something like:
public HomeController(IUserService service)
{
using (var disposable = service.Wrap())
{
var user = service.GetUser();
// I can even grab it again, implicitly.
IUserService service2 = disposable;
}
}
Now regardless of whether that concrete implementation of IUserService is disposable or not, I can still safely work on the assumption that it doesn't matter.
Another quick console example:
class Program
{
static void Main(string[] args)
{
using (var instance = new ClassA().Wrap())
{
ClassA instanceA = instance;
}
using (var instance = new ClassB().Wrap())
{
ClassB instanceB = instance;
}
Console.ReadKey();
}
}
public class ClassA
{
}
public class ClassB : IDisposable
{
public void Dispose()
{
Console.Write("Disposed");
}
}

usage of autofac compared with a simple IoC implementation

I am currently using/experimenting with autofac as my IoC controller.
Previously to this I used a simple static class defining two methods, similar to
public static TService Resolve<TService>()
public static void Register<IType, ImpType>()
where ImpType must be of IType.
Now over to autofac. When registering, you might do something like
builder.RegisterType<ProductRepository>().As<IProductRepository>();
however if ProductRepository is-not-a IProductRepository you don't get a compile error?
Is there some way of wiring things up more safely if desired?
Secondly, when building my Ioc modules I use something like
public static class IoCContainer
{
public static IContainer BaseContainer { get; private set; }
public static void Build(ContainerBuilder builder)
{
BaseContainer = builder.Build();
}
}
After I have called IoCContainer.Build(..) I can no longer register anything 'into' the BaseContainer. Compare this with the simple model where you can register anything from anywhere. Perhaps this is by design?
I think the .RegisterType<Foo>.As<IFoo> pattern is not type safe simply because the C# compiler (or the CLR type system) does not handle such type constraints. For example, the following hypothetical declaration of the As method won't compile:
interface IRegistration<TImplementation>
{
void As<TContract>() where TImplementation : TContract;
}
The compiler error is "'SomeNamespace.IRegistration.As()' does not define type parameter 'TImplementation'".
Is there some way of wiring things up more safely if desired?
The following seems to work (though it is discouraged by the best practices section on the Autofac wiki). It will give a compiler error unless Foo implements IFoo:
var builder = new ContainerBuilder();
builder.Register<IFoo>(c => new Foo()).SingleInstance();
var container = builder.Build();
var foo = container.Resolve<IFoo>();
c is the IComponentContext. If the Foo constructor requires a constructor argument then you can write c => new Foo(c.Resolve<IBar>()).
After I have called IoCContainer.Build(..) I can no longer register anything 'into' the BaseContainer
You can update the container in Autofac 2.2.

Categories