Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/274.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# Ninject:在绑定时定义命名约束_C#_Dependency Injection_Ninject - Fatal编程技术网

C# Ninject:在绑定时定义命名约束

C# Ninject:在绑定时定义命名约束,c#,dependency-injection,ninject,C#,Dependency Injection,Ninject,目前,我正在重构一个旧项目,并试图用Ninject实现依赖注入 我遇到了一个或多或少简单的问题。我找到了一个有效的解决方案,但我不确定这是否是解决这个问题的最佳方法 我试图尽可能准确地解释情况: 我有一个接口ITool: public interface ITool { string Caption { get; set; } string Name { get; } IAction[] Actions { get; } } 还有一个抽象类AbstractTool(

目前,我正在重构一个旧项目,并试图用Ninject实现依赖注入

我遇到了一个或多或少简单的问题。我找到了一个有效的解决方案,但我不确定这是否是解决这个问题的最佳方法

我试图尽可能准确地解释情况:

我有一个接口
ITool

public interface ITool 
{
    string Caption { get; set; }
    string Name { get; }

    IAction[] Actions { get; }
}
还有一个抽象类
AbstractTool
(具体内容与问题无关)

此外,我还有派生类
GenericTool

public class GenericTool : AbstractTool 
{
    private readonly string furtherInformation;

    public override string FurtherInformation
    { 
       get { return furtherInformation; } 
    }

    public GenericTool (string furtherInformation, string caption, string name, Action[] actions)
        : base(caption, name, actions)
    {
       this.furtherInformation= furtherInformation;
    }        
}
在某一点上,这个
GenericTool
被使用并实例化了几次,如下所示:

new OtherObject(
{
   new List<GenericTool>
   {
      new GenericTool("info1","caption1","name1", new IActions[]
         { new Action1(), new Action2()}),
      new GenericTool("info2","caption2","name2", new IActions[]
         { new Action3(), new Action4()}),
        ...
   }
}...
操作的绑定:

Bind<IAction>.To<Action1>().Named("SpecialTool1Action");
Bind<IAction>.To<Action2>().Named("SpecialTool1Action");
Bind<IAction>.To<Action3>().Named("SpecialTool2Action");
Bind<IAction>.To<Action4>().Named("SpecialTool2Action");
函数
GetLateNamedConstructorArgument

private IAction[] GetLateNamedConstructorArgument(IContext context)
{
    IEnumerable<IAction> actions= context.Kernel.
            GetAll<IAction>("SpecialTool1Action");
    return actions.ToArray();
}
private IAction[]GetLateNamedConstructorArgument(IContext上下文)
{
IEnumerable actions=context.Kernel。
GetAll(“特殊工具1行动”);
返回操作。ToArray();
}
对于上一个解决方案,我在没有创建几十个类的情况下得到了相同的结果

但是有没有更好的办法来解决这个问题呢?我可以用其他方式声明所需绑定的名称吗?可能还有其他的工作吗

编辑

我想象这样的情况:

Bind<ITool>().To<GenericTool>()
   ...
.WithConstructorArgument("actions", [Named("SpecialTool1Action")]);
Bind().To())
...
.带有构造函数参数(“操作”,命名为(“SpecialTool1操作”));

Ninject使用
SpecialTool1Action
名称注入所有操作

沿着这条路线走下去的问题是,正如在的文档中所提到的,这通常是错误的

这里更好的方法是使用模式

抽象工厂模式提供了一种封装一组 具有共同主题但未指定主题的单个工厂 具体课程

基本上,您不是让DI容器在代码中传播以满足复杂的需求,而是请求工厂并使用它们创建所需的实例

Ninject提供了几种实现方法,例如

在Ninject v3中,您可以使用扩展。这个文档链接有一大堆示例代码。以下是说明该概念的主要内容:

public class Foo
{
    readonly IBarFactory barFactory;

    public Foo(IBarFactory barFactory)
    {
        this.barFactory = barFactory;
    }

    public void Do()
    {
        var bar = this.barFactory.CreateBar();
        ...
    }
}

public interface IBarFactory
{
    Bar CreateBar();
}

根据您的回答,我可以创建一个
IGenericToolFactory
IActionFactory
。如果我在
OtherObject
中使用
IGenericToolFactory
,我需要声明我要使用的工具的具体信息(在
OtherObject
中)。但这不符合我的要求,因为
OtherObject
也用于
GenericTool
的不同实例。(我可以有多个
OtherObject
的实例以及其他具有其他操作的GenericTools)。此外,我无法在不修改它的情况下替换
OtherObject
中的工具。然而,如果我要为此使用
AbstractFactory
,我仍然不知道如何将正确的工具与正确的操作连接起来。
private IAction[] GetLateNamedConstructorArgument(IContext context)
{
    IEnumerable<IAction> actions= context.Kernel.
            GetAll<IAction>("SpecialTool1Action");
    return actions.ToArray();
}
Bind<ITool>().To<GenericTool>()
   ...
.WithConstructorArgument("actions", [Named("SpecialTool1Action")]);
public class Foo
{
    readonly IBarFactory barFactory;

    public Foo(IBarFactory barFactory)
    {
        this.barFactory = barFactory;
    }

    public void Do()
    {
        var bar = this.barFactory.CreateBar();
        ...
    }
}

public interface IBarFactory
{
    Bar CreateBar();
}