如何使用Light Inject将参数传递给构造函数?

问题描述 投票:24回答:3

Light Inject允许您在解析时将参数传递给构造函数吗?我想知道这两个框架是否都执行Unity的ResolverOverride或DependencyOverride两者。

inversion-of-control light-inject
3个回答
26
投票

我怀疑这个问题是关于在实际解决服务时将原始值传递给构造函数的。

让我们设置一个简单的测试类:

public interface IFoo
{

}

public class Foo : IFoo
{
    public Foo(string value)
    {

    }
}

Foo类采用一个字符串参数,在解析IFoo服务时我们希望提供该参数。

var container = new ServiceContainer();
container.Register<string, IFoo>((factory, value) => new Foo(value));
var firstFoo = container.GetInstance<string, IFoo>("SomeValue");
var secondFoo = container.GetInstance<string, IFoo>("AnotherValue");

如果我们希望能够不直接使用容器而创建Foo类的新实例,我们可以简单地注入一个函数委托。

public interface IBar { }

public class Bar : IBar
{
    public Bar(Func<string, IFoo> fooFactory)
    {
        var firstFoo = fooFactory("SomeValue");
        var secondFoo = fooFactory("AnotherValue");
    }
}

“组合根”现在看起来像这样:

var container = new ServiceContainer();
container.Register<string, IFoo>((factory, value) => new Foo(value));
container.Register<IBar, Bar>();
var bar = container.GetInstance<IBar>();

如果问题是关于将“静态”原始值传递给构造函数,则只需注册这样的工厂委托即可。

var container = new ServiceContainer();
container.Register<IFoo>((factory) => new Foo("SomeValue"));
var firstInstance = container.GetInstance<IFoo>();
var secondInstance = container.GetInstance<IFoo>();

不同之处在于该方法不允许您在解析时传递值。该值是在注册时静态指定的。


21
投票

Simple Injector可能最简单的选择是向委托人注册

[Test]
public void Test1()
{
    Container container = new Container();

    container.Register<IClassWithParameter>(() => new ClassWithParameter("SomeValue"));

    var result = container.GetInstance<IClassWithParameter>();
}

public interface IClassWithParameter { }

public class ClassWithParameter : IClassWithParameter
{
    public ClassWithParameter(string parameter)
    {
    }
}

详细介绍了用于注入原始依赖项的高级选项here


8
投票

如果您的构造函数没有任何其他依赖项(或者您想手动解决这些依赖项,则上面的命令都可以使用)。如果您遇到以下情况,尽管它掉下来了:

public class Test : ITest
{
   private IFoo _foo;
   public Test(string parameter, IFoo foo)
   {
      _foo = foo;
      ....
   }
}

现在,您不仅必须手动插入字符串,而且还需要Foo。因此,现在(完全)您根本不使用依赖注入。同样是简单注入器状态:

简单注入器不允许注入基本类型(例如 整数和字符串)转换为构造函数。

我的理解是,他们说的是“不要这样做”。

可扩展性点

这里的另一个选择是使用"Extensibillity points" for this scenario

为此,您需要从注入的元素中提取硬编码元素:

public class Test : ITest
{
   private IFoo _foo;
   public Test(IFoo foo)
   {
      _foo = foo;
      ....
   }

  public void Init(string parameter)
  {

  }
}

您现在可以注入您的附属对象您的硬编码元素:

_container.Register<ITest, Test>();
_container.RegisterInitializer<Test>(instance => {instance.Init("MyValue");});

如果现在添加另一个依赖项,则注入现在可以进行,而无需更新配置,即代码仍然可以很好地解耦:

public class Test : ITest
{
   private IFoo _foo;
   private IBar _bar;
   public Test(IFoo foo, IBar bar)
   {
      _foo = foo;
      _bar = bar;
      ....
   }

  public void Init(string parameter)
  {

  }
}
© www.soinside.com 2019 - 2024. All rights reserved.