Given the following code, how do I resolve the right SomeInstance in autofac?
public class BaseClass {}
public class SubClass1 : BaseClass {}
public class
Autofac supports open generics. You can use the following code if generics type is known at compile time:
var builder = new ContainerBuilder();
builder.RegisterGeneric(typeof(SomeInstance1<>))
.As(typeof(IGenericInterface<>));
var container = builder.Build();
var instance1 = container.Resolve<IGenericInterface<SubClass1>>();
Assert.IsInstanceOfType(typeof(SomeInstance1<SubClass1>), instance1);
If type parameter is not known until runtime (which is likely your case if you want to iterate through collection of types) then you can build your type using MakeGenericType:
var typeInRuntime = typeof (SubClass1);
var instance1 = container.Resolve(typeof(IGenericInterface<>).MakeGenericType(typeInRuntime));
Correction. You cannot call MakeGenericType from the Container. I solved the issue of instantiating Generics using the 'TYPE' as the parameter on the Resolve call. The builder is registered.
builder.RegisterGeneric(typeof (FakeRepository<>)).As(typeof (IRepository<>)).OnActivating(e =>
{
var typeToLookup = e.Parameters.FirstOrDefault() as TypedParameter;
if (typeToLookup != null)
{
var respositoryType = typeof (FakeRepository<>);
Type[] typeArgs = {typeToLookup.Value.GetType()};
var genericType = respositoryType.MakeGenericType(typeArgs);
var genericRepository = Activator.CreateInstance(genericType);
e.ReplaceInstance(genericRepository);
}
});
Then the resolution happens like this, passing a TypedParameter to the Resolve. In this case I have a list of items (IItem) that are resolved that I want to create a repository for all of the items of that type.
var items = container.Resolve<IEnumerable<IItem<string>>>();
foreach (var item in items)
{
var repository = container.Resolve(typeof (IRepository<DataItemBase>), new TypedParameter(item.GetType(), item));
Assert.IsNotNull(repository);
}
Thanks for your post it helped and I Hope this update helps.