如何将构造函数注入与"手动"构造函数参数组合?即.
public class SomeObject
{
public SomeObject(IService service, float someValue)
{
}
}
Run Code Online (Sandbox Code Playgroud)
我的DI容器应该解析/注入IService,并且应该指定someValue.我该如何混合这两个?
在任何需要运行时值来构造特定依赖项的地方,Abstract Factory就是解决方案.
我的问题是:为什么很多来源都赞成FactoryInterface而不是FactoryDelegate来实现这种模式?两种解决方案的优缺点是什么?
这是一个了解我的意思的例子
如果您的服务需要具有特定上下文的存储库,则服务构造函数需要工厂来创建或访问其存储库.
对此的常见解决方案是创建这样的RepositoryFactoryInterface.
public IRepositoryFactory {
IRepository Create(ContextInformation context);
}
public class MyService {
private IRepositoryFactory repositoryFactory;
public MyService(IRepositoryFactory repositoryFactory)
{
this.repositoryFactory = repositoryFactory:
}
public void DoSomeService()
{
ContextInformation context = ....;
IRepository repository = this.repositoryFactory.Create(context);
repository.Load(...);
...
repository.Save(...);
}
}
Run Code Online (Sandbox Code Playgroud)
您还需要以某种方式实现IRepositoryFactory接口
public MyEf4RepositoryFactory : IRepositoryFactory
{
IRepository Create(ContextInformation context)
{
return new MyEf4Repository(context);
}
}
Run Code Online (Sandbox Code Playgroud)
...并在应用程序中使用它
public void main()
{
IRepositoryFactory repoFactory = new MyEf4RepositoryFactory();
IService service = new MyService(repoFactory);
service.DoSomeService();
}
Run Code Online (Sandbox Code Playgroud)
-----主流解决方案结束------ …
如何使用Ninject处理带静态方法的类?
也就是说,在C#中,一个接口中不能有静态方法,而Ninject在使用接口的基础上工作?
我的用例是一个类,我希望它有一个静态方法来创建一个未填充的自身实例.
编辑1
只是在TopologyImp类中添加一个示例,在GetRootNodes()方法中,如何创建一些要返回的iNode类?我会用正常的代码练习构建这些或者我会以某种方式使用Ninject吗?但是,如果我使用容器创建那么我没有给IOC这个库知识呢?
public interface ITopology
{
List<INode> GetRootNodes();
}
public class TopologyImp : ITopology
{
public List<INode> GetRootNodes()
{
List<INode> result = new List<INode>();
// Need code here to create some instances, but how to without knowledge of the container?
// e.g. want to create a few INode instances and add them to the list and then return the list
}
}
public interface INode
{
// Parameters
long Id { get; set; }
string Name { …Run Code Online (Sandbox Code Playgroud) 我经常读到IOC中的服务定位器是一种反模式.
去年我们将IOC(特别是Ninject)介绍给了我们的工作应用程序.该应用程序是遗留的,它非常大,而且它是碎片化的.有很多方法可以创建类或类链.有些是由Web框架(自定义)创建的,有些是由nHibernate创建的.很多地方都散落在奇怪的地方.
我们如何处理不同的场景,而不是提出一些至少不是ServiceLocatorish的东西,而不是在不同的地方使用不同的内核(像singleton,HttpRequest和thread这样的范围很重要).
编辑我将添加更多细节,以便我们了解当前的SL模式.
事实上,我们不希望多个内核.我们只想要一个(实际上因为SL我们只有一个静态的).这是我们的设置:
1)我们在7-8个不同的项目/组件中有Ninject模块.当我们的应用程序(webapp)启动时,模块通过程序集扫描收集并加载到内核中并放置在服务定位器中.所以这一切都相当昂贵.
2)我们有一个自定义UI框架,结构很开心.想想大约120个选项卡表单,每个表单构建1-10个标签页作为其生命周期的一部分.SL战略性地用于5-6个地方,其覆盖所有这些作为纯分辨率或仅进行后实例化注入属性.
3)UI下的任何内容都不在那些顶级调用中,如果这些类想要使用IOC,他们需要提出自己的策略.有各种不同的小框架,每个框架都是他们自己的小世界.
因此,从我所阅读的内容中做到这一点的理想方法是在需要访问IOC时注入内核......这一切都很好,很好; 我们确实将SL的使用保持在最低限度.
但是我从哪里获得这个内核?我不想在任何地方构建和注册新的.似乎我必须从静态上下文或工厂中获取它,因此我可以确保我正在使用的内核保持其他人正在使用的相同范围的对象,并且还要避免注册所有模块.在那一点上,无论那个东西看起来很像服务定位器吧?
请记住,这个应用程序是巨大的,紧密耦合.我们没有多次花几个月的时间来重构它.对于我们来说,SL似乎是一种很好的方式,可以在我们有时间的地方慢慢地工作.
castle-windsor ninject ioc-container unity-container service-locator
Kernel.Get()线程安全吗?我的目标是在我的所有组件中共享我的内核实例,他们可能会在不同的线程上同时调用Kernel.Get().
Kernel.Get()线程安全吗?
在所有位于不同dll中的应用程序组件之间共享应用程序内核的最佳模式是什么?如果这是有意义的,我不希望将工厂的实例传递给我的应用程序的每个组件.
我习惯于在Web应用程序中使用IoC/DI - 主要是使用MVC3的Ninject.我的控制器是为我创建的,充满了所有依赖关系,子依赖关系等.
但是,胖客户端应用程序的情况有所不同.我必须创建自己的对象,或者我必须恢复到服务定位器样式方法,我要求内核(可能通过某个接口,允许可测试性)给我一个完整的依赖项对象.
但是,我已经看到Service Locator被描述为反模式的几个地方.
所以我的问题是 - 如果我想在我的胖客户端应用程序中受益于Ninject,是否有更好/更正确的方法来获得所有这些?
请注意我不只是在这里讨论MVVM并将视图模型放入视图中.这特别是需要从内核提供存储库类型对象,然后从该存储库中提取的实体注入了功能(当然数据来自数据库,但它们也需要一些对象作为参数,具体取决于状态世界,Ninject知道如何提供).我可以以某种方式做到这一点,而不会将存储库和实体都作为不可测试的混乱吗?
如果有什么不清楚,请告诉我.谢谢!
编辑7月14日
我确信提供的两个答案可能是正确的.然而,我身体的每一根纤维都在对抗这种变化; 其中一些可能是由于缺乏知识造成的,但也有一个具体原因导致我无法看到这种做事方式的优雅;
我没有在原始问题中解释得这么好,但问题是我正在编写一个库,将被几个(首先是4-5,可能更晚)的WPF客户端应用程序使用.这些应用程序都在相同的域模型等上运行,因此将它们保存在一个库中是保持DRY的唯一方法.但是,该系统的客户也有可能编写自己的客户端 - 我希望他们有一个简单,干净的库来与之交谈.我不想强迫他们在他们的作文根中使用DI(在他的书中使用像Mark Seeman这样的术语) - 因为与他们相比,只需要新建一个MyCrazySystemAdapter()并使用它就可以使事情复杂化.
现在,MyCrazySystemAdapter(因为我知道人们会在这里不同意我选择的名称)需要由子组件组成,并使用DI组合在一起.MyCrazySystemAdapter本身不需要注入.它是客户端与系统通信所需的唯一接口.因此,一个客户应该得到其中一个,DI就像魔术一样在幕后发生,并且该对象由许多不同的对象使用最佳实践和原则组成.
我确实意识到这将成为一种想要做事的有争议的方式.但是,我也知道将成为此API客户的人员.如果他们发现他们需要学习并连接DI系统,并在他们的应用程序入口点(Composition Root)中提前创建他们的整个对象结构,而不是新建一个对象,他们会给我中指和直接搞乱数据库并以你难以想象的方式搞砸了.
TL; DR:为客户端提供结构合理的API太麻烦了.我的API需要提供一个单独的对象 - 使用DI和适当的实践在幕后构建 - 他们可以使用.现实世界有时胜过为了坚持模式和实践而向后建造一切的愿望.
dependency-injection ninject testability thick-client service-locator
我有以下代码
public class Something {
[Inject]
public Configuration config {get;set;} //singleton
[Inject]
public Provider<WindowHandler> windowsProvider { get; set; } //NOT singleton
public void Search(string text) {
WindowHandler handler = windowsProvider.Create(xxxxxx);
//use the new handler that was created
}
}
Run Code Online (Sandbox Code Playgroud)
但似乎提供商采用了IContext,我放了xxxxxx.不应该使用IContext从我引导并从内核创建Something.cs时使用.Provider上的no参数Create方法在哪里??? (我来自Guice的土地观点,它将被编码如上).
所以问题是如何正确地做到这一点?
谢谢,迪恩
我在家里玩 Ninject 一个简单的测试平台项目,只是想看看我能用它做什么。作为起点,我正在为某些服务构建一个控制台运行程序,它接受各种参数,并根据它所输入的内容,使用为流畅的界面提供的相同方法来配置要运行的模型。
举个例子,假设我有一个详细的开关,/o. /o可以作为/o:quiet, /o:normal, 或 传递/o:verbose。各种选项是不言自明的。
为了满足这个论点,我想附上各种实现ILogger- quiet 获取一个仅打印关键消息的安静记录器,normal 获取一个普通记录器,而verbose 获取一个打印所有内容的健谈记录器。
我想做的是模块中的一些事情,例如:
Bind<ILogger>().To<QuietLogger>().When(VerbosityParameter=="quiet");
Bind<ILogger>().To<VerboseLogger>().When(VerbosityParameter=="verbose");
Run Code Online (Sandbox Code Playgroud)
...等等。
我不知道如何做这样的事情;所有的条件绑定似乎都依赖于注入目标的状态。这样做有什么意义?当消费类必须准确详细地指定确定给定的具体类型所需的所有条件时,它难道不会打败依赖注入的全部要点吗?为什么我不能告诉 Ninject 我想要什么,然后得到它?
这是我第一次尝试使用DI,我选择了ninject因为它据说很容易学习,并且有这个问题.
我正在创建这样的对象:
var registrants = JsonConvert.DeserializeObject<List<Registrant>>(input);
Run Code Online (Sandbox Code Playgroud)
我目前有这个构造函数 Registrant
[Inject]
public Registrant(IMemberRepository memberRepository)
{
_memberRepository = memberRepository;
}
Run Code Online (Sandbox Code Playgroud)
使用Ninject将存储库依赖项注入反序列化对象的最佳方法是什么?
我听到有人说你不应该使用Service Locator进行依赖注入.那么如何在不依赖服务定位器的情况下注入依赖项呢?我想尝试IoC容器,但不想陷入反模式.
你应该只设置一切所以有一个地方所有类总是有最深层的依赖链?(如果我/它完全有意义)
我对你的所有代码都依赖于所选的IoC容器是不对的,是吗?
那么你在哪里"使用"你的容器(用于重新解析)?你如何解决所有问题,就像你的代码一样深入?它是通过每层直到前层使用接口来正确设计所有内容的一部分吗?
或者我只是错过了一点?
让我提醒你,我只是不想陷入反模式,需要一些提示/提醒它.