C#/Autofac – 注册目录下的所有类,并使用它们的字符串名称解析

huangapple go评论122阅读模式
英文:

C#/Autofac - Register ALL classes under a directory, and resolve using their string names

问题

这是一个链接 - https://stackoverflow.com/questions/35975635/autofac-register-and-resolve-with-names,但我需要它更加动态。

我有一个库,将会添加许多新的类。让我们称它们为 NewClass1NewClass2,等等,所有这些类都继承自 AbstractBaseClass 抽象类。

builder.RegisterAssemblyTypes(libraryAssembly)
			.Where(t => t.IsSubclassOf(typeof(AbstractBaseClass)));

我能够像这样解析 NewClass1/2/3/...

container.Resolve<NewClass1>()

但我需要自己指定类的名称,而且它不能是类的 string 名称。

有没有什么指导?我正在寻找类似这样的东西,

container.Resolve("NewClass1")

// 或者

container.Resolve("NewClass2")

TIA

英文:

Found this - https://stackoverflow.com/questions/35975635/autofac-register-and-resolve-with-names, but I need it to be more dynamic

I have a library, where a lot of new classes will be added. Let's call them NewClass1, NewClass2, etc., and all these classes inherit AbstractBaseClass abstract class.

builder.RegisterAssemblyTypes(libraryAssembly)
			.Where(t =&gt; t.IsSubclassOf(typeof(AbstractBaseClass)));

I am able to resolve NewClass1/2/3/... like this

container.Resolve&lt;NewClass1&gt;()

but I need to specify the class name myself, and it cannot be a string name of the class.

Any pointers anyone? I am looking for something like,

container.Resolve(&quot;NewClass1&quot;)

// or

container.Resolve(&quot;NewClass2&quot;)

TIA

答案1

得分: 2

以下是您要翻译的代码部分:

var containerBuilder = new ContainerBuilder();

containerBuilder
    .RegisterAssemblyTypes(Assembly.GetCallingAssembly())
    .Where(x => x.IsSubclassOf(typeof(ClassA)))
    .Named<ClassA>(t => t.Name);

var container = containerBuilder.Build();

var b = (ClassB)container.ResolveNamed<ClassA>("ClassB");
var c = (ClassC)container.ResolveNamed<ClassA>("ClassC");
containerBuilder
    .Register((context, parameters) =>
    {
        var name = parameters.TypedAs<string>();
        if (context.TryResolveNamed<ClassA>(name, out var service)) return service;
        throw new InvalidOperationException();
    })
    .As<ClassA>();

... 

var factory = container.Resolve<Func<string, ClassA>>();

var b = (ClassB)factory("ClassB");
var c = (ClassC)factory("ClassC");
英文:

You can try something as below:

var containerBuilder = new ContainerBuilder();

containerBuilder
    .RegisterAssemblyTypes(Assembly.GetCallingAssembly())
    .Where(x =&gt; x.IsSubclassOf(typeof(ClassA)))
    .Named&lt;ClassA&gt;(t =&gt; t.Name);

var container = containerBuilder.Build();

var b = (ClassB)container.ResolveNamed&lt;ClassA&gt;(&quot;ClassB&quot;);
var c = (ClassC)container.ResolveNamed&lt;ClassA&gt;(&quot;ClassC&quot;);
    

You can take it further and create a factory like this:

containerBuilder
    .Register((context, parameters) =&gt;
    {
        var name = parameters.TypedAs&lt;string&gt;();
        if (context.TryResolveNamed&lt;ClassA&gt;(name, out var service)) return service;
        throw new InvalidOperationException();
    })
    .As&lt;ClassA&gt;();

... 

var factory = container.Resolve&lt;Func&lt;string, ClassA&gt;&gt;();

var b = (ClassB)factory(&quot;ClassB&quot;);
var c = (ClassC)factory(&quot;ClassC&quot;);

huangapple
  • 本文由 发表于 2023年4月13日 20:51:03
  • 转载请务必保留本文链接:https://go.coder-hub.com/76005648.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定