I seem to be doing this a fair bit in my code:
public class ActionsModule : Module
{
protected override void Load(ContainerBuilder builder)
{
base.Load(builder);
builder.Register(c => LogManager.GetCurrentClassLogger()).As<ILog>().InstancePerDependency();
// Autofac doesn't seem to be able to inject things without explicit binding
builder.RegisterType<ComboActions>().As<ComboActions>().InstancePerHttpRequest();
builder.RegisterType<AppActions>().As<AppActions>().InstancePerHttpRequest();
}
}
}
Where the 'actions' class is a class I require to be injected into my controller, and has various other sub-dependencies.
Seems a bit rubbish. Why can't autofac resolve that the class has a constructor with dependencies that are already satisfied and manufacture an instance automatically?
I mean, if class A requires class B to be injected and class B requires C, D, E, etc. fair enough, I guess you dont want to walk the entire dependency chain to see if you can make a class at run time. ...but if class A directly depends on C and D which are explicitly bound, surely that's a trivial case?
Am I missing something? Can't seem to see any documentation for this...
You don't have to register every type. Autofac provides a AnyConcreteTypeNotAlreadyRegisteredSource that will automatically grab a concrete type if you haven't already provided a registration.
For example:
var builder = new ContainerBuilder();
builder.RegisterSource(new AnyConcreteTypeNotAlreadyRegisteredSource());
var container = builder.Build();
...
var myConcreteType = container.Resolve<MyConcreteType>();
The sources allow more complex things, like automatically injecting mocked objects for interfaces and abstract class based dependencies.
AFAIK, Autofac requires every needed type to be registered in the container, but this does not mean you have to do each one individually. Almost 99% of my registrations are handled by adding this attribute to the type:
[AttributeUsage(AttributeTargets.Class)]
public class AutoRegisterAttribute : Attribute { }
So for example, you'd have
[AutoRegister]
class ComboActions
{
And then I register them with this:
public class AutoScanModule : Module
{
private readonly Assembly[] _assembliesToScan;
public AutoScanModule(params Assembly[] assembliesToScan)
{
_assembliesToScan = assembliesToScan;
}
protected override void Load(ContainerBuilder builder)
{
builder.RegisterAssemblyTypes(_assembliesToScan)
.Where(t => t.GetCustomAttributes(typeof (AutoRegisterAttribute), false).Any())
.AsSelf()
.AsImplementedInterfaces()
.InstancePerLifetimeScope();
}
}
Like I said, this covers most of my registrations and then I usually only have to worry about things like 3rd party types, open generics and decorators.
EDIT: Check out the reply from Kaleb that proves me wrong. Cool feature I never knew about!
Related
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
Say I have a service that I want to resolve with a scoped lifetime. But sometime I try to resolve it as the interface type and sometimes at the implementation type.
The first thing I tried to do was this:
ServiceCollection services;
services.AddScoped<MyClass>();
services.AddScoped<IMyInterface, MyClass>();
The problem with the above sample is that a different instance is used if I resolve IMyInterface, and than resolve MyClass. Basically it's possible that 2 scoped instances are alife at the same time.
I work around this issue in the following way. But it's very error-prone because you can easily forget to do this at one place, and it's really hard to notice.
serviceCollection.AddScoped<MyClass>();
serviceCollection.AddScoped<IMyInterface, MyClass>(sp => sp.GetRequiredService<MyClass>());
Is there any way to accomplish what I want in a way that is less error prone. Preferrably, but not necessarily, in a single registration?
I.e. as an xUnit test:
public class Tests
{
[Fact]
public void ReturnsSameInstanceForImplementationAndServiceType()
{
var serviceCollection = new ServiceCollection();
// TODO: Change these lines so they're less error prone.
serviceCollection.AddScoped<MyClass>();
serviceCollection.AddScoped<IMyInterface, MyClass>(sp => sp.GetRequiredService<MyClass>());
var services = serviceCollection.BuildServiceProvider();
var myInt = services.GetRequiredService<IMyInterface>();
var myCls = services.GetRequiredService<MyClass>();
Assert.Equal(myCls, myInt);
}
class MyClass : IMyInterface { }
interface IMyInterface { }
}
One option would be to create your own extension method that wraps up the two lines you've shown in your question. For example:
public static class ServiceCollectionExtensions
{
public static void AddScopedInterfaceAndClass<TInterface, TClass>(this IServiceCollection serviceCollection)
where TInterface : class
where TClass : class, TInterface
{
serviceCollection.AddScoped<TClass>();
serviceCollection.AddScoped<TInterface, TClass>(sp => sp.GetRequiredService<TClass>());
}
}
You could call this like so:
serviceCollection.AddScopedInterfaceAndClass<IMyInterface, MyClass>();
I appreciate that AddScopedInterfaceAndClass isn't the perfect name - it's just an example to demonstrate the idea. Also, there is still the downside that you'd have to remember to use this extension rather then AddScoped.
Note: You could simplify the second AddScoped in the extension method by removing the second generic (TClass) as this is inferred by the compiler.
So we have ran into what seems like a very common issue with StructureMap and IoC containers in general I assume. Bidirectiona/Circuar dependencies.
Given the following code, it is currently causing a circular dependency since we have it 'autowiring' properties.
public class ServiceA:IServiceA
{
public IServiceB ServiceBDependency {get;set;}
}
public class ServiceB:IServiceB
{
public IServiceA ServiceADependency {get;set;}
}
I see the 'dependency' of each of these on eachother, however, I feel that as a property, they are not true dependencies which is what separates them from using constructor injection.
It seems that there should be a way for these services to be resolved...and then have the properties injected after the objects have been created?
I know of various ways to get around this, including the true clean way of rearchitecting my services, but i am curious as to what options I have with instantiation and service registration with StructureMap. It seems like a fairly common issue that would need a solution.
I'd like to show you my approach. I am using only the setter injection. And we often have many objcets referencing each other, in our web app. E.g. IUserFacade requires IUserState on user creation while IUserState requires IUserFacade on userState deletion (to check for constraint).
e.g.:
public interface IUserFacade
{
... // User facade Add, Update, Delete
IUserStateFacade { set; }
}
public interface IUserStateFacade
{
...
IUserFacade { set; }
}
In reality, we have many objects with cross references, and even more complicated. And it would really be very costy, if all the referenced objects should be created each time, even if not used during the request. We need the "lazy", the proxy objects to be placed in the setters.
The way how to do it, is a mix of the: 1) StructureMap (IoC top) and 2) Castle (proxying top) libraries. Below I will show some snippets of objects needed for this solution. More could be found inside open source project Catharsis
Wrapper. This object would be injected into each Property by SM (StructureMap) instead of real implementor. It is the sleeping implementation. It is waiting for a first call. If it will never happen (IUserFacade is deleting user, no need to access referenced IUserStateFacade during such request) this wrapper will sleep for ever (request). Once touched, SM will create the real object and Wrapper will pass all calls to that.
The Castle interceptor:
public class Wrapper : IInterceptor
{
object _lazy;
protected readonly Type Type;
public Wrapper(Type type)
{
Type = type;
}
public void Intercept(IInvocation invocation)
{
if (_lazy.IsNull()) // lazily instantiate the instance
{
_lazy = ObjectFactory.GetInstance(Type);
}
try
{
var method = invocation.Method;
if (method.ContainsGenericParameters)
{
method = method.MakeGenericMethod(invocation.GenericArguments);
}
invocation.ReturnValue = method.Invoke(_lazy, invocation.Arguments);
}
catch (TargetInvocationException ex)
{
// PublishingManager.Publish(.... // publish exception
throw;
}
}
}
ProxyInstance. Now, we need an object, clear and understandable to SM. That object will be mapped to all interfaces (IUserFacade...) Instead of returning implementation of the UserFacade.
We can also use our custom AOP filters here.
This ProxyInstance will be provided with the real implementor type, and building up the Wrapper.
The StructureMap Instance:
public class ProxyInstance : Instance
{
protected readonly ProxyGenerator Factory = new ProxyGenerator();
protected readonly Type ConcreteType;
public ProxyInstance(Type type)
{
ConcreteType = type; // the type for our Wrapper, the real implementation
}
protected override object build(Type pluginType, BuildSession session)
{
var aopFilters =
// my custom way how to inject more AOP filters
AopFilterManager.GetFilters()
// the core for us, one of the interceptors is our Wrapper
.Union(new[] { new Wrapper(ConcreteType) })
.ToArray();
// Castle will emit a proxy for us, but the Wrapper will do the job
var proxy = Factory
.CreateClassProxy(ConcreteType, AopFilterManager.AopOptions, aopFilters);
return proxy;
}
And now just use some standard way how to map it in the SM (I am using custom ProxyConvention but it is out of the scope here). Let's use simplified explicit mapping:
registry
.For<IUserFacade>()
.HybridHttpOrThreadLocalScoped()
.Use(new ProxyInstance(typeof(UserFacade)));
...
Also, each of our objects created via SM, implements IService. So, the default setter injection could be set like this:
registry.SetAllProperties
(
set => set.TypeMatches
(
type => type
.GetInterfaces()
.Any(i => i.IsEquivalentTo(typeof(IService)))
)
);
From that moment, when we need to work with a IUserFacade (the direct ObjectFactory call, or accessed via Wrapper), we recieve the real implementor. All its properties (setter injection) will be pre-populated with our ProxyInstance / Wrapper.
If any of these properties is accessed, e.g. IUserStateFacade the same (discribed above for IUserFacade) will happen again.
Because the Lifecycle is Thread or Request based, we have only one implementor in runtime/web request
Because we do inject the Wrappers while using setter injection, no issues with circular infinite loops. Only the first level is injected each time
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.
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.