C# 为Ninject提供它可以使用的构造函数依赖项';无法解决?
免责声明:我对DI和IoC很陌生,请原谅任何严重的误解 考虑一个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
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:这似乎更像是一个设计问题,而不是一个关键问题。没有更多的背景,很难说。您只需确定一次字符串,因此很可能需要您在设置之后执行所有绑定。记住,我绝不是一个九项专家。