Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/heroku/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 为参数的具体名称注册字符串值_C#_Inversion Of Control_Ioc Container_Autofac - Fatal编程技术网

C# 为参数的具体名称注册字符串值

C# 为参数的具体名称注册字符串值,c#,inversion-of-control,ioc-container,autofac,C#,Inversion Of Control,Ioc Container,Autofac,我使用的是Autofac,我有几个类要求输入字符串类型的参数和名称为lang的参数。有没有办法将字符串值注册到所有名为“lang”的参数中,以便自动解析?我不想编辑任何构造函数,因为它不是我的代码(我知道接受例如CultureInfo会使注册更容易…) 导致简短语法的东西,如 builder.Register(lang=>“en-US”).As()。命名为(“lang”) 这将是理想的 谢谢。看看这个例子: builder.Register<ClassName>((c, p) =&g

我使用的是Autofac,我有几个类要求输入字符串类型的参数和名称为lang的参数。有没有办法将字符串值注册到所有名为“lang”的参数中,以便自动解析?我不想编辑任何构造函数,因为它不是我的代码(我知道接受例如CultureInfo会使注册更容易…)

导致简短语法的东西,如 builder.Register(lang=>“en-US”).As()。命名为(“lang”)

这将是理想的


谢谢。

看看这个例子:

builder.Register<ClassName>((c, p) =>
{
var p2 = p.Named<string>("lang");
return new ClassName(p2);
});
var container = builder.Build();
var m = container.Resolve<ClassName>(new NamedParameter("lang", "en-US"));
var m2 = container.Resolve<ClassName>(new NamedParameter("lang", "fr-FR"));
builder.Register((c,p)=>
{
变量p2=p.命名(“lang”);
返回新的类名(p2);
});
var container=builder.Build();
var m=container.Resolve(新名称参数(“lang”、“en-US”);
var m2=container.Resolve(新名称参数(“lang”、“fr”);

您可以解析类并在构造函数中传递参数。

解决此问题的一个相当简单的方法是使用自定义Autofac模块

首先,实现模块并处理IComponentRegistration.Preparing事件。这也是存储参数值的位置:

using System;
using Autofac;
using Autofac.Core;

public class LangModule : Module:
{
  private string _lang;
  public LangModule(string lang)
  {
    this._lang = lang;
  }

  protected override void AttachToComponentRegistration(
    IComponentRegistry componentRegistry,
    IComponentRegistration registration)
  {
    // Any time a component is resolved, it goes through Preparing
    registration.Preparing += InjectLangParameter;
  }

  protected void InjectLangParameter(object sender, PreparingEventArgs e)
  {
    // Add your named parameter to the list of available parameters.
    e.Parameters = e.Parameters.Union(
      new[] { new NamedParameter("lang", this._lang) });
  }
}
现在您有了自定义模块,您可以将其与其他依赖项一起注册,并提供希望注入的值

var builder = new ContainerBuilder();
builder.RegisterModule(new LangModule("my-language"));
builder.RegisterType<LangConsumer>();
...
var container = builder.Build();
var builder=newcontainerbuilder();
注册模块(新语言模块(“我的语言”);
RegisterType();
...
var container=builder.Build();
现在,当您解析任何具有字符串参数“lang”的类型时,您的模块将插入您提供的值


如果需要更具体,可以使用事件处理程序中的PreparingEventArgs来确定要解析的类型(
e.Component.Activator.LimitType
)等。然后您可以动态决定是否包含参数。

这很有效,但是,需要自动为每个类执行此解析,这与当前场景相同,只是语法不同。我正在寻找一种可以自动为所有类(或给定程序集的所有类)解析此参数的方法。当调用Register时,可以在其中传递工厂方法。您可以传递类似于
()=>{returnnewclassname(GetLangString());}
的内容,但它仍然需要为构造函数中具有“stringlang”的所有类调用此函数。我正在寻找一个O(1)行代码的解决方案,而不是O(涉及的类数)LOC。我已经检查了构建器单元测试,我认为你不能用Autofac实现这一点。我还没试过,但看起来和我想要的一模一样。非常感谢。@Travis-这也可以用于属性注入吗?我相信可能可以,但我将把它作为“读者的练习”