gpt4 book ai didi

c# - Ninject:注入(inject)两个相同类型的不同对象

转载 作者:太空狗 更新时间:2023-10-29 19:43:03 25 4
gpt4 key购买 nike

如果我有一个类,它对同一类型具有双重依赖性(需要两个不同的实例),如果实例之间的唯一区别是更深层次的依赖性,那么让 Ninject 执行 DI 并保留两个图的最佳方法是什么分开?

示例对象图:

foo → ClassA → ClassB
bar → ClassA → ClassB

C 类的构造函数:

public class C
{
public C(ClassB foo, ClassB bar) { … }
}

那么我如何确保使用 foo 实例化的 ClassB 被提供为 ClassB 依赖 foo , 和 bar ... bar?

只是为了一些背景,我有一些需求更改,所以我需要用复合只写存储库替换只写存储库 (IAdd)

public class CompositeWriteRepository<T> : IAdd<T>
{
public CompositeWriteRepository(IAdd<T> foo, IAdd<T> bar, Func<T, bool> descriminator) { ... }
public Add(T entity)
{
if (descriminator(entity)) {
foo.Add(entity);
} else {
bar.Add(entity);
}
}
}

通过 mocking,这很容易,我可以使用名称注入(inject):

 kernel.Bind<IAdd<EntityType>>().To<fooRepository>().Named("foo");
kernel.Bind<IAdd<EntityType>>().To<barRepository>().Named("bar");

kernel.Bind<IAdd<EntityType>>().To<CompositeWriterRepository<EntityType>>()
.WithConstructorArgument("foo", x => x.Kernel.Get<IAdd<EntityType>>("foo")
.WithConstructorArgument("bar", x => x.Kernel.Get<IAdd<EntityType>>("bar");

当我使用真正的存储库时,问题就来了; foobar 最终写入文件,因此它们需要不同的文件名。由于它们是 StreamWriter 存储库,因此它们的依赖项之一实际上获得了两个不同的文件名。

string FileName → FileStreamWriterFactory → StreamRepository → CompositeRepository

到目前为止我发现构造东西的唯一方法是创建一个命名的 FileName,命名为 FileStreamWriterFactory,命名为 StreamRepository × 2 (一次用于 foo,一次用于 bar)。这似乎是很多的工作,所以我希望有更好的解决方案。

如果需要,我可以重新架构,感觉这是一种优雅的方式,可以在需求发生变化时快速添加分隔条目。我意识到我的类(class)都非常具体,但我认为单一职责通常会支持这一点,在我的情况下,我们编写了一堆小应用程序并有更多我们可以满足的请求,因此这是拥有大量可重用代码的好方法我基本上只需要为不同的任务重新配置。

解决方案
Remo Gloor 应该得到赞扬;这可能是最佳实践。

我实际上做的是创建一个新的扩展

public static bool WhenAnchester(this IRequest request, Func<IRequest, bool> conditions)
{
var parentContext = request.ParentContext;
if (parentContext == null) {
return false;
}

return conditions(parentContext.Request) ||
parentContext.Request.WhenAnchester(conditions);
}

这让我可以轻松控制将哪个文件注入(inject)到哪个存储库。

kernel.Bind<string>().ToConstant("Foo.txt")
.When(x => x.Target.Name == "filepath" &&
x.WhenAnchester(t => t.Target != null && t.Target.Name == "Dest1"));

kernel.Bind<string>().ToConstant("Bar.txt")
.When(x => x.Target.Name == "filepath" &&
x.WhenAnchester(t => t.Target != null && t.Target.Name == "Dest2"));

可能有更好的解决方案,所以我没有必要向其他人推荐它,但它对我来说效果很好。

最佳答案

是的,有更好的方法

参见 https://github.com/ninject/ninject/commit/60443badf4ef840531c93e9287b154a9bba337c2

它是 3.0,但 IsAnyAnchestorNamed 也可以在 When 条件下与 2.2 一起使用。

关于c# - Ninject:注入(inject)两个相同类型的不同对象,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9404389/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com