Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/lua/3.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#_.net_Dependency Injection_Inversion Of Control_Ninject - Fatal编程技术网

C# 为Ninject提供它可以使用的构造函数依赖项';无法解决?

C# 为Ninject提供它可以使用的构造函数依赖项';无法解决?,c#,.net,dependency-injection,inversion-of-control,ninject,C#,.net,Dependency Injection,Inversion Of Control,Ninject,免责声明:我对DI和IoC很陌生,请原谅任何严重的误解 考虑一个ClassB,它需要一个实现IClassA的对象。Ninject应该能够将ClassA的实例注入ClassB的构造函数,假设它能够构造ClassA的实例: public class ClassA : IClassA { public ClassA(string runtimeDependency) { /* ... */ } } public class ClassB : IClassB { public Clas

免责声明:我对DI和IoC很陌生,请原谅任何严重的误解

考虑一个
ClassB
,它需要一个实现
IClassA
的对象。Ninject应该能够将
ClassA
的实例注入
ClassB
的构造函数,假设它能够构造
ClassA
的实例:

public class ClassA : IClassA
{
    public ClassA(string runtimeDependency) { /* ... */ }
}

public class ClassB : IClassB
{
    public ClassB(IClassA depA) { /* ... */ }
}

public sealed class TestBootstrapModule : NinjectModule
{
    public override void Load()
    {
        Bind<IClassA>().To<ClassA>();
        Bind<IClassB>().To<ClassB>();
    }
} 
公共类ClassA:IClassA
{
公共类A(字符串运行时依赖项){/*…*/}
}
公共类B:IClassB
{
公共类B(IClassA depA){/*…*/}
}
公共密封类TestBootstrapModule:NinjectModule
{
公共覆盖无效负载()
{
绑定()到();
绑定()到();
}
} 
现在,让我们假设一些运行时逻辑涉及到导出提供给
ClassA
string runtimeDependency
。我应该如何为Ninject提供
运行时依赖关系
,以便它能够为
ClassB
提供
ClassA
的实例

字符串只确定一次,因此我不需要担心向每个实例中注入新值。

一种方法是通过方法提供
ClassA
。还要记住,对于Ninject 2,您不需要模块,可以直接在内核中进行绑定

Bind<IClassA>().ToMethod(_ => 
  {
     // do something interesting with a runtimeDependancy
     return new ClassA(someInterestingVariable);
  });
Bind()
{
//使用RuntimeDependence做一些有趣的事情
返回新的ClassA(someInterestingVariable);
});

我真的在试探运行时变量何时可用以及它的作用域。

根据您的设计和具体问题,这里有一些选项。第一个最简单的解决方案是,当您向Ninject请求服务时,只提供价值

Kernel.Get<IClassA>("runtimeDependencyValue");
然后我将我的服务构造函数装饰成这样:

public class ClassA : IClassA
{
    public ClassA([ConnectionString("AppDB")] string runtimeDependency) { /* ... */ }
}
Bind<string>()
    .ToMethod(ctx => 
    {
        var attr = (ConnectionStringAttribute)context.Request.Target.GetCustomAttributes(typeof(ConnectionStringAttribute), true).First();
        string settingName = string.IsNullOrEmpty(attr.SettingName) ? context.Request.Target.Name : attr.SettingName;
        return ConfigurationManager.ConnectionStrings[settingName].ConnectionString;
    })
    .WhenTargetHas<ConnectionStringAttribute>();
最后,我的绑定将如下所示:

public class ClassA : IClassA
{
    public ClassA([ConnectionString("AppDB")] string runtimeDependency) { /* ... */ }
}
Bind<string>()
    .ToMethod(ctx => 
    {
        var attr = (ConnectionStringAttribute)context.Request.Target.GetCustomAttributes(typeof(ConnectionStringAttribute), true).First();
        string settingName = string.IsNullOrEmpty(attr.SettingName) ? context.Request.Target.Name : attr.SettingName;
        return ConfigurationManager.ConnectionStrings[settingName].ConnectionString;
    })
    .WhenTargetHas<ConnectionStringAttribute>();
Bind()
.ToMethod(ctx=>
{
var attr=(ConnectionStringAttribute)context.Request.Target.GetCustomAttributes(typeof(ConnectionStringAttribute),true).First();
string settingName=string.IsNullOrEmpty(attr.settingName)?context.Request.Target.Name:attr.settingName;
返回ConfigurationManager.ConnectionString[settingName].ConnectionString;
})
.WhenTargetHas();

你明白了。希望这有帮助:)

我很高兴您提到了变量的生存期和范围;如果绑定时变量还不存在怎么办?(我相信我应该尽早在一个公共位置初始化所有绑定。)@robjb:这似乎更像是一个设计问题,而不是一个关键问题。没有更多的背景,很难说。您只需确定一次字符串,因此很可能需要您在设置之后执行所有绑定。记住,我绝不是一个九项专家。