C# 在Autofac部件扫描和注册期间,如何有选择地更改寿命范围?

C# 在Autofac部件扫描和注册期间,如何有选择地更改寿命范围?,c#,singleton,autofac,C#,Singleton,Autofac,我有一个类,它使用AutoFac从二进制文件夹中的程序集构建容器。这实际上是在dll上进行迭代,并使用接口注册类: private static void RegisterAssembly(ContainerBuilder builder, string assemblyNamePattern) { // Get the path to the currently executing assembly. We will load dll's from here o

我有一个类,它使用AutoFac从二进制文件夹中的程序集构建容器。这实际上是在dll上进行迭代,并使用接口注册类:

    private static void RegisterAssembly(ContainerBuilder builder, string assemblyNamePattern)
    {
        // Get the path to the currently executing assembly. We will load dll's from here only.
        var path = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
        if (String.IsNullOrWhiteSpace(path))
            return;

        // Get a list of all the assemblies in this folder
        var assembliesToRegister = (Directory.EnumerateFiles(path, assemblyNamePattern, SearchOption.TopDirectoryOnly)
                .Select(Assembly.LoadFrom)
                .ToArray());

        // Register the dll's
        builder.RegisterAssemblyTypes(assembliesToRegister).AsImplementedInterfaces();
    }
这很好,我可以创建我需要的类的实例。我遇到的问题是,这些类中有两个是单例类(例如Redis缓存),因此需要注册为单例类。在代码中,它们是使用Lazy定义的:

private static readonly Lazy _instance=new Lazy(()=>new CacheManager());
公共静态ICacheManager实例
{
获取{return}instance.Value;}
}

我想知道的是,是否有办法告诉AutoFac某些类需要注册为单例。我猜我可以在容器构建后检查它,并将特定定义更改为单例,但如果我可以让Autofac在注册时自动执行,则更可靠。

作为一种廉价的解决方案,当扫描DLL时,可以排除一个或多个接口:

        // Register the dll's, except the singleton ones.
        builder.RegisterAssemblyTypes(assembliesToRegister)
                .AsImplementedInterfaces()
                .Except<IOne>()
                .Except<ITwo>();
//注册dll,但单例dll除外。
builder.RegisterAssemblyTypes(assembliesToRegister)
.AsImplementedInterfaces()
.除()
.除();
这允许自动注册除单例之外的所有内容。接下来,注册单身人士:

AddSingletonInstance<IOne>(builder, assembliesToRegister, "OneType");
AddSingletonInstance<ITwo>(builder, assembliesToRegister, "TwoType");
addsingletonistance(builder,assembliesToRegister,“OneType”);
添加SingleTonInstance(生成器、assembliesToRegister,“TwoType”);
这依赖于扫描先前创建的程序集列表的常规方法:

    private static void AddSingletonInstance<T>(ContainerBuilder builder, Assembly[] assembliesToRegister, string typeName)
    {
        var singletonType = (from asm in assembliesToRegister
                        from tt in asm.DefinedTypes
                        where tt.Name == typeName
                        select tt).FirstOrDefault();

        if (singletonType != null)
            builder.RegisterType(singletonType).As<T>().SingleInstance().ExternallyOwned();
    }
private static void addsingletonistance(ContainerBuilder builder,Assembly[]assembliesToRegister,string typeName)
{
var singletonType=(来自assembliesToRegister中的asm
来自asm.DefinedTypes中的tt
其中tt.Name==typeName
选择tt).FirstOrDefault();
if(singletonType!=null)
builder.RegisterType(singletonType).As().SingleInstance().ExternallyOwned();
}

虽然不太理想,但它可以工作。

您使用哪种版本的Autofac?版本3.5.2(对不起,应该在帖子中添加)。我已经取得了一些进展,现在我正在注册程序集并使用它来排除单例类。然后我将它们分别注册为SingleInstance().ExternallyOwned()。这不是一个很好的解决方案,但学习速度很快!使用LINQ包含/排除某些类型实际上是对您的问题的答案-您应该发布该问题并接受您自己的答案。
    private static void AddSingletonInstance<T>(ContainerBuilder builder, Assembly[] assembliesToRegister, string typeName)
    {
        var singletonType = (from asm in assembliesToRegister
                        from tt in asm.DefinedTypes
                        where tt.Name == typeName
                        select tt).FirstOrDefault();

        if (singletonType != null)
            builder.RegisterType(singletonType).As<T>().SingleInstance().ExternallyOwned();
    }