繁体   English   中英

Autofac和泛型

[英]Autofac and generics

我有这堂课

public class MyViewModel<T> where T : class
{
    public MyViewModel(
        Func<IEnumerable<T>, MyService<T>> myServiceFactory,
        IEnumerable<T> list) 
    { 
    }
}

我需要在引导程序中注册Func

我尝试了类似的东西

builder.Register<Func<IEnumerable<T>, MyService<T>>>(c =>
{
    var ctx = c.Resolve<IComponentContext>();

    return collection => ctx.Resolve<MyService<T>>(collection);
});

但我无法正常运作。 谁能帮我?

正如您已经注意到的,您尝试执行的操作不会编译。 没有在某个地方定义T ,C#编译器将无法理解。 如果没有静态定义的T ,则必须使用反射来定义类型,但是很快就会达到Autofac和C#的极限。 您的代码变得非常讨厌。 相反,您必须在辅助方法中提取以下代码:

private static void RegisterMyServiceFactory<T>(IContainerBuilder builder) {
    builder.Register<Func<IEnumerable<T>, MyService<T>>>(c =>
    {
        var ctx = c.Resolve<IComponentContext>();

        return collection => ctx.Resolve<MyService<T>>(collection);
 });

使用此方法时,需要为应用程序中需要的每个T调用此方法:

RegisterMyServiceFactory<Customer>(builder);
RegisterMyServiceFactory<Order>(builder);
RegisterMyServiceFactory<Employee>(builder);

这个解决方案并不是特别好,但这是因为您缺少抽象。 不要让消费者依赖Func<IEnumerable<T>, MyService<T>> ,而应创建特定的抽象供消费者依赖:

public interface IServiceFactory<T> {
    MyService<T> Resolve(IEnumerable<T> collection);
}

并将您的代码嵌入IServiceFactory<T>实现中:

private sealed class AutofacServiceFactory<T> : IServiceFactory<T> {
    private readonly IComponentContext context;
    public AutofacServiceFactory(IComponentContext context) {
        this.context = context;
    }

    public MyService<T> Resolve(IEnumerable<T> collection) {
        return context.Resolve<MyService<T>>(collection);
    }
}

您可以按以下方式注册此开放通用类型:

builder.RegisterGeneric(typeof(AutofacServiceFactory<>))
    .As(typeof(IServiceFactory<>));

如果builder.Register代码是由MyViewModel的实例执行的,则可以/应该工作。

否则,这取决于在特定上下文中如何/是否声明T,并且您需要提供更多信息。

无论如何,您的问题似乎与autofac无关。 它与泛型的使用有关。 Register方法确实是通用方法,但是在进行调用时,必须将通用参数最终转换为具体类型。 因此,除非在对builder.Register的调用上下文中正确声明了T,否则它将无法正常工作,因为您似乎正在尝试注册整个类型的类型。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM