0

我有一个像这样的构造函数,我想从工厂传递参数:

public Event(IRegisteredType registeredEarly, IPassNow passNowByInterface,
                               DateTimeOffset local, DateTimeOffset world)
{
    // ...
}

我尝试了这种方法,但它不起作用,因为本地和世界价值观相同,一个覆盖另一个:

public Event CreateEvent(IPassNow passNow, DateTimeOffset local, DateTimeOffset world)
{
    var args = new Arguments { { typeof(IPassNow), passNow } };
    args.InsertTypedCollection(new object[] { local, world });
    return _container.Resolve<Event>(args);
}
  • registerEarly 应该自动解析,它在组合根目录中注册,并且有效
  • passNowByInterface 应该在解析时传递,但因为它是一个接口,我需要指定接口类型,否则 Castle Windsor 将尝试使用参数的具体类型,同样有效 - 请参阅使用 Castle 传递通用参数失败温莎
  • local 和 world 也需要在解析时传递,但请注意它们都是相同的具体类型,我不能依赖变量名 - 请参阅Castle Windsor 中相同类型的解析时参数
  • 我不能让最后一个与其他人一起工作?
4

3 回答 3

2

Resolve方法有几个重载。Arguments类型很简单IDictionary,因此键不能相同。

如果您尝试Arguments使用其构造函数创建一个实例,您将得到一个“System.ArgumentException”(已添加具有相同键的项目。)

var args = new Arguments(new object[] {passNow, local, world});

如果您调试代码,您会看到字典中只有两个项目。

var args = new Arguments {{typeof (IPassNow), passNow}};
args.InsertTypedCollection(new object[] {local, world});

为了使其工作,参数可以作为匿名类型传递。

container.Resolve<Event>(new {passNow = passNow, local = local, world = world});

有一个测试可以证明

[Fact]
public void ArgumentsAsAnonimusType()
{
    // Arrange.
    var container = new WindsorContainer();
    container.Register(Component.For<Event>().ImplementedBy<Event>());
    container.Register(Component.For<IRegisteredType>().ImplementedBy<RegisteredType>());
    var passNow = new PassNow();
    var local = DateTimeOffset.Now;
    var world = DateTimeOffset.UtcNow;
    local.Should().NotBe(world);

    // Act.
    var result = container.Resolve<Event>(new { passNow = passNow, local = local, world = world });

    // Assert.
    result.Should().BeOfType<Event>();
    result.RegisteredType.Should().Be(container.Resolve<IRegisteredType>());
    result.PassNow.Should().Be(passNow);
    result.Local.Should().Be(local);
    result.World.Should().Be(world);
}
于 2014-03-08T17:06:15.860 回答
1

你的工厂是什么样子的?你试过 TypedFactoryFacility 吗?

例如,在我的项目中,我有一个这样的构造函数:

public SomeConcrete(ILog log, IDataBase dataBase, int param1, int param2, int param3, bool somebool)

我的工厂是:

public interface IFactory
{
    SomeConcrete GetSomeConcrete(int param1, int param2, int param3, bool somebool);
}

并且通过变量名解析工作正常。

如果您不习惯使用类型化工厂,您可以尝试:

container.Resolve<ISomeConcrete>(new {param1 = 1, param2 = 2, param3 = 3, somebool = false});

更多信息在这里类型化工厂设施

也许也很有用。

于 2014-03-09T13:13:33.843 回答
0

以为我找到了解决方案:

public Event CreateEvent(IPassNow passNow, DateTimeOffset local, DateTimeOffset world)
{
    var args = new Arguments(new { local, world });
    args.Insert(typeof(IPassNow), passNow);
    return _container.Resolve<Event>(args);
}

但这也不适用于混淆,结果是 new Arguments(new { local, world }); 也使用参数文字名称而不是按顺序或其他东西匹配..所以这不是一个真正的答案..

于 2014-03-09T20:10:55.583 回答