I am trying to configure an Autofac module which seems to have a complex requirement.
here goes:
I have a common interface:
public interface IMyInterface<TFoo, TBar>
I have a bunch of classes implementing this interface
eg.
class MyImpl1 : IMyInterface<string, bool> { } class MyImpl2 : IMyInterface<bool, string> { } class MyImpl3 : IMyInterface<bool, string> { }
Finally, I have a decorator:
class MyDecorator<TFoo, TBar> : IMyInterface<TFoo, TBar>
I only want to "decorate" implementations (from MyInterface ) that have a specific attribute. Thus, all implementations of MyInterface that have the [MyAttribute] attribute are decorated with MyDecorator.
I'm near, but not cigars yet:
var builder = new ContainerBuilder(); builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()) .Where(type => type.GetCustomAttributes(true) .Any(attr => attr.GetType() == typeof(MyAttribute))) .AsClosedTypesOf(typeof (IMyInterface<,>)) .Keyed("CachableQueries", typeof(IMyInterface<,>)); builder.RegisterGenericDecorator(typeof(MyDecorator<,>), typeof(IMyInterface<,>), "CachableQueries"); var container = builder.Build(); Console.WriteLine(container.Resolve<IMyInterface<string,bool>>()); Console.WriteLine(container.Resolve<IMyInterface<bool,bool>>());
I understand that the last piece of the puzzle is the key, it really needs to pass the type to Keyed("CachableQueries", THE_TYPE); but it does not play the ball.
Update
Nemesv sent me in the right direction.
As part of my question, I forgot to mention that I also needed to register all IMyInterface <,> implementations that did not have [MyAttribute].
I did this in two steps. First register the types with Decorator, and then register the rest.
My solution: I know that it needs refactoring, but as a proof of concept. it works.
class Program { static void Main(string[] args) { var builder = new ContainerBuilder();