如何在autofac中注册所有实现了通用接口的类?

22

我已经创建了一个通用接口,它应该将实体映射到视图模型并反向映射。我需要在Autofac配置中进行约80个注册。是否可以批量注册它们?以下是接口:

public interface ICommonMapper<TEntity, TModel, TKey>
    where TEntity : BaseEntity<TKey>
    where TModel : BaseEntityViewModel<TKey>
    where TKey : struct 
{
    TModel MapEntityToModel(TEntity entity);
    TModel MapEntityToModel(TEntity entity, TModel model);
    TEntity MapModelToEntity(TModel model);
    TEntity MapModelToEntity(TModel model, TEntity entity);
}

谢谢!


2
你有80个ICommonMapper的实现吗? - Cyril Durand
大约有80种实体类型...其中大约有80个可以进行CRUD操作。 - Roman
4个回答

40
你可以使用:
builder.RegisterAssemblyTypes(assemblies)
       .AsClosedTypesOf(typeof(ICommonMapper<,,>));

assemblies 是您的类型所属的程序集的集合。

如果您有一个继承自 ICommonMapper<Person, PersonModel, Int32>PersonMapperAutofac 将能够解析 ICommonMapper<Person, PersonModel, Int32>


必须向 Builder 提供 IAssemblyFinder,才能顺利工作。 - Roman

9
不需要把它复杂化,您只需像下面这样正常注册接口的所有实现即可:

enter image description here

然后Autofac会自动注入该接口的实现,当它看到类似这样的构造函数中的可枚举/数组界面时。enter image description here 我使用了这种方法,它完全按照我的预期工作。希望能帮到你。干杯

1
那段代码存在内存泄漏问题,因为你捕获了一个 IEnumerator<T> 的引用,但没有将其释放 - 我猜你没有这样做,因为你的类没有实现 IDisposable 接口。你能解释一下为什么选择这种方式而不是保留一个 IEnumerable<T> 字段吗? - Mickaël Derriey
嗨,Mick,感谢您的评论,我同意我们需要处理这些实例,但这不是我在这里回答的重点。我只想给你们举个例子,展示如何使用Autofac将特定接口的实现数组注入到特定实例中。因为我只想将ICommandChainFeature的实现注入到我的CommandChain类中,所以不保留IEnumerable<T>字段 :) - Hung Vu
1
我明白你的意思,但为什么不使用private readonly IEnumerable<ICommandChainFeature> _features;而不是IEnumerator<ICommandChainFeature>呢? - Mickaël Derriey
我使用IEnumerable是因为我想在需要时使用foreach循环,这是非常基本的知识。您可以使用List<T>、T数组或任何类型的列表/数组,Autofac会为您完成相同的操作。希望能对您有所帮助...如果您觉得我的回答有用,请点赞。谢谢。 - Hung Vu
1
没关系。你的领域是枚举器,而不是可枚举对象。我的问题与 OP 的问题无关,所以我就到这里了。抱歉离题了,我只是好奇。 - Mickaël Derriey
1
80个一个一个地注册?))) 不!我太懒了!))) - Roman

0

这里有另一种方法可以通过typeFinder来实现:

var mappers = typeFinder.FindClassesOfType(typeof(ICommonMapper<,,>)).ToList();
        foreach (var mapper in mappers)
        {
            builder.RegisterType(mapper)
                .As(mapper.FindInterfaces((type, criteria) =>
                {
                    var isMatch = type.IsGenericType &&
                                  ((Type)criteria).IsAssignableFrom(type.GetGenericTypeDefinition());
                    return isMatch;
                }, typeof(ICommonMapper<,,>)))
                .InstancePerLifetimeScope();
        }

-1

你可以告诉 Autofac 注册所有实现某个接口的内容。我不得不从几个 DLL 中加载很多东西,所以我做了这样的事情,你应该能够根据自己的需求进行调整:

以下是一个示例,你应该能够根据自己的需求进行调整:

foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies())
            {
                if (assembly.FullName.Contains("someNameYouCareAbout"))
                {
                    builder.RegisterAssemblyTypes(assembly)
                   .AsImplementedInterfaces();
                }
            }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接