35

给定以下代码,如何在 autofac 中解析正确的 SomeInstance?

public class BaseClass {}

public class SubClass1 : BaseClass {}

public class SubClass2 : BaseClass {}

public interface IGenericInterface<T> where T : BaseClass {}

public class SomeInstance1<T> : IGenericInterface<T> where T : SubClass1

public class SomeInstance2<T> : IGenericInterface<T> where T : SubClass2

我想根据子类上泛型的类型选择 SomeInstance1 或 2 。

因此,例如,我有一个子类的集合(SubClass1、2....),并且在迭代它们时我想选择正确的 SomeInstance 类。

4

2 回答 2

72

Autofac 支持开放泛型。如果泛型类型在编译时已知,则可以使用以下代码:

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);

如果直到运行时才知道类型参数(如果您想遍历类型集合,这很可能是您的情况),那么您可以使用 MakeGenericType 构建您的类型:

        var typeInRuntime = typeof (SubClass1);
        var instance1 = container.Resolve(typeof(IGenericInterface<>).MakeGenericType(typeInRuntime));
于 2009-11-09T07:02:35.270 回答
4

更正。您不能从容器中调用 MakeGenericType。我解决了使用“TYPE”作为 Resolve 调用的参数来实例化泛型的问题。建造者已注册。

        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);
            }
        });

然后解析像这样发生,将 TypedParameter 传递给 Resolve。在这种情况下,我有一个已解决的项目列表 (IItem),我想为该类型的所有项目创建一个存储库。

        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);
        }

感谢您的帖子,它有所帮助,我希望此更新有所帮助。

于 2014-10-31T19:59:45.987 回答