如何使用 Ninject MVC3 将 IDBContextFactory 正确注入到控制器的注入 IDomainFactory 中?
准备工作
- 我正在使用 Ninject.MVC3 2.2.2.0 Nuget Package 将 IDomain 接口的实现注入到我的控制器中,该接口使用工厂方法分离我的业务逻辑 (BL)。
我正在使用以下方法在预配置的 NinjectMVC3.cs 中注册我的 Ninject 模块:
private static void RegisterServices(IKernel 内核) { var 模块 = 新 INinjectModule[] { 新的 DomainBLModule(), 新的 ADOModule() }; 内核.Load(模块); }
我试图避免恶魔服务定位器的致命诅咒 反模式。
域类使用 DBContext,我也尝试通过 IDBContext 注入接口实现,具体情况如下:
IDomainBLFactory:
public interface IDomainBLFactory
{
DomainBL CreateNew();
}
DomainBLFactory:
public class DomainBLFactory : IDomainBLFactory
{
public DomainBL CreateNew()
{
return new DomainBL();
}
}
在控制器的命名空间:
public class DomainBLModule : NinjectModule
{
public override void Load()
{
Bind<IDomainBLFactory>().To<DomainBLFactory>().InRequestScope();
}
}
此时,我可以使用 Ninject 构造函数注入将 IDomainBLFactory 实现注入到我的控制器中,没有任何问题:
public class MyController : Controller
{
private readonly IDomainBLFactory DomainBLFactory;
// Default Injected Constructor
public MyController(IDomainBLFactory DomainBLFactory)
{
this.DomainBLFactory = DomainBLFactory;
}
... (use the Domain for performing tasks/commands with the Database Context)
}
现在是我的中心问题。
在DomainBL实现中,我将再次使用IDBContextFactory将依赖项注入到特定的DBContext,在本例中是来自实体框架的ADO DBContext:
IDbDataContextFactory
public interface IDbDataContextFactory
{
myADOEntities CreateNew();
}
DbDataContextFactory
public class DbDataContextFactory : IDbDataContextFactory
{
public myADOEntities CreateNew()
{
return new myADOEntities ();
}
}
ADOModule 现在,在DomainBL
public class ADOModule : NinjectModule
{
public override void Load()
{
Bind<IDbDataContextFactory>().To<DbDataContextFactory>().InRequestScope();
}
}
实现中,我遇到了为 DBContext 对象工厂注入必要接口的问题:
public class DomainBL
{
private readonly IDbDataContextFactory contextFactory;
**** OPS, i tried to understand about 10+ Stackoverflow articles ***
...
}
我尝试了什么?
使用构造函数注入。但我不知道在 IDBContextFactory 中对 Factory CreateNew() 的调用中要注入什么。为了清楚:
公共类DomainBLFactory:IDomainBLFactory { // 这里构造函数需要一个参数来传递工厂实现。 公共域BL CreateNew() { return new DomainBL(??????) // 我需要一个 IDBContextFactory impl 来解析。 //这不像MVC控制器那样在内部进行注入 //对于控制器构造函数。我在控制器之外 } }
在此有用Post,我们独特的真正朋友 Remo Gloor 在评论中为我描述了一个可能的解决方案,并引用:“创建一个具有 CreateSomething 方法的界面,该方法可以获取您需要的一切创建实例并让它返回实例。然后在您的配置中实现此接口并将 IResolutionRoot 添加到其构造函数,并使用此实例获取所需的对象。”
问题:如何使用 Ninject.MVC3 和我适度的域类方法以正确的方式实现这一点?如何解析 IResolutionRoot 而不因服务定位器反模式中的中继而受到惩罚?
对 IDBContexFactory 使用属性注入。在学习和阅读所有矛盾的观点以及相关理论解释的过程中,我可以推断这不是为我的 DBContexFactory 类代码进行注入的正确方法。没关系。反正也没用。
公共类DomainBL { [注入] 公共 IDbDataContextFactory contextFactory { 得到; 放; } //不起作用,无论有无参数构造函数,contextFactory 都是 null ....(使用 contextFactory.CreateNew() 的方法.... }
问题:我缺少什么?即使这种方法是错误的,属性也不会注入。
被诅咒。使用 DependencyResolver 并接受这种耻辱。这是可行的,我将继续采用这种方法,直到找到合适的解决方案。这确实令人沮丧,因为在过去 10 天的努力中,我试图理解并正确地做事,但缺乏知识。
公共类DomainBL { 私有只读 IDbDataContextFactory contextFactory; this.contextFactory = DependencyResolver.Current.GetService
(); //太棒了,它有效……但我是个罪人。 } 问题:我对接口实现注入的工厂方法和使用域驱动方法来分解业务逻辑?如果我错了,我应该自信地实施哪些模式堆栈?
我之前看到过很多文章和博客都没有以公开、清晰的方式提出这个重要的问题。
Remo Gloor 在 www.planetgeek.ch/2011/12/31/ninject-extensions-factory-introduction 中介绍了 Ninject 3.0.0 RC 的 Ninject.Extensions.Factory。
问题:此扩展是否可以与 Ninject.MVC3 一起用于一般海豚?在这种情况下,这应该是我对不久的将来的希望。
预先感谢大家的指导,并记住我们感谢您的善意帮助。我想很多人也会发现这个场景也很有用。
Preliminaries
- I'm using Ninject.MVC3 2.2.2.0 Nuget Package for injecting into my controller an implementation of a IDomain Interface that separates my Business Logic (BL) using an Factory approach.
I'm registering my Ninject Modules in the preconfigured NinjectMVC3.cs using:
private static void RegisterServices(IKernel kernel) { var modules = new INinjectModule[] { new DomainBLModule(), new ADOModule() }; kernel.Load(modules); }
I'm trying to avoid the fatal curse of the diabolic Service Locator anti-pattern.
The Domain Class uses a DBContext that i'm trying to inject an interface implementation too, via an IDBContext, with the following scenario:
IDomainBLFactory:
public interface IDomainBLFactory
{
DomainBL CreateNew();
}
DomainBLFactory:
public class DomainBLFactory : IDomainBLFactory
{
public DomainBL CreateNew()
{
return new DomainBL();
}
}
In the controller's namespace:
public class DomainBLModule : NinjectModule
{
public override void Load()
{
Bind<IDomainBLFactory>().To<DomainBLFactory>().InRequestScope();
}
}
At this point i can inject the IDomainBLFactory implementation into my controller using Ninject Constructor Injection without any problem:
public class MyController : Controller
{
private readonly IDomainBLFactory DomainBLFactory;
// Default Injected Constructor
public MyController(IDomainBLFactory DomainBLFactory)
{
this.DomainBLFactory = DomainBLFactory;
}
... (use the Domain for performing tasks/commands with the Database Context)
}
Now my central problem.
In the DomainBL implementation, i will inject the dependency to a particular DBContext, in this case ADO DBContext from Entity Framework, again, using a IDBContextFactory:
IDbDataContextFactory
public interface IDbDataContextFactory
{
myADOEntities CreateNew();
}
DbDataContextFactory
public class DbDataContextFactory : IDbDataContextFactory
{
public myADOEntities CreateNew()
{
return new myADOEntities ();
}
}
ADOModule
public class ADOModule : NinjectModule
{
public override void Load()
{
Bind<IDbDataContextFactory>().To<DbDataContextFactory>().InRequestScope();
}
}
Now in the DomainBL implementation I faced the problem of injecting the necessary interface for the DBContext Object Factory:
public class DomainBL
{
private readonly IDbDataContextFactory contextFactory;
**** OPS, i tried to understand about 10+ Stackoverflow articles ***
...
}
What have I tried?
To Use the constructor Injection. But I don't know what to inject in the call for the Factory CreateNew() in the IDBContextFactory. For clear:
public class DomainBLFactory: IDomainBLFactory { // Here the constructor requires one argument for passing the factory impl. public DomainBL CreateNew() { return new DomainBL(?????) // I need a IDBContextFactory impl to resolve. //It's not like in the MVC Controller where injection takes place internally //for the controller constructor. I'm outside a controller } }
In this Useful Post, our unique true friend Remo Gloor describes in a comment a possible solution for me, citing: "Create an interface that has a CreateSomething method that takes everything you need to create the instance and have it return the instance. Then in your configuration you implement this interface and add an IResolutionRoot to its constructor and use this instace to Get the required object."
Questions: How do I implement this in a proper way using Ninject.MVC3 and my modest Domain Class approach? How do I Resolve the IResolutionRoot without be punished for relaying in the Service Locator anti-pattern?
To Use the property injection for an IDBContexFactory. In the course of learning and reading all the contradictory points of view plus the theoretical explanations about it, I can deduce it's not a proper way of doing the injection for my DBContexFactory class code. Nevermind. It doesn't work anyway.
public class DomainBL { [Inject] public IDbDataContextFactory contextFactory { get; set; } //Doesn't works, contextFactory is null with or without parameterless constructor .... (methods that uses contextFactory.CreateNew().... }
Question: What am I missing? Even if this approach is wrong the property is not injecting.
Be cursed. Use a DependencyResolver and live with the stigmata. This works and I will remain in this approach until a proper solution appears for me. And this is really frustrating because the lack of knowledge in my last 10 days effort trying to understand and do things right.
public class DomainBL { private readonly IDbDataContextFactory contextFactory; this.contextFactory = DependencyResolver.Current.GetService<IDbDataContextFactory>(); //So sweet, it works.. but i'm a sinner. }
Question: Is there a big mistake in my understanding of the Factory Approach for the injection of interfaced implementations and using a Domain Driven Approach for taking apart the Business Logic? In the case I'm wrong, what stack of patterns should I implement with confidence?
I saw before a really big quantity of articles and blogs that does not ask this important question in a open a clear way.
Remo Gloor introduces the Ninject.Extensions.Factory for the Ninject 3.0.0 RC in www.planetgeek.ch/2011/12/31/ninject-extensions-factory-introduction.
Question: Will this extension work coupled with Ninject.MVC3 for general porpouse?. In such case it should be my hope for the near future.
Thank you all in advance for your guidance and remember we appreciate your kind help. I think a lot of people will find this scenario useful too.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我不太明白你们工厂的目的。通常,对于一个请求,您只有一个 ObjectContext 实例。这意味着您不需要工厂,只需在请求范围中绑定
myADOEntities
并将其注入到您的DomainBL
中,而无需添加工厂:是的,工厂和 mvc 扩展可以工作一起。
I don't really get the purpose of your factories. Normally, you have exactly one ObjectContext instance for one request. This means you don't need the factory and can simply bind
myADOEntities
in Request scope and inject it into yourDomainBL
without adding the factories:And Yes the factory and mvc extrensions work together.
下面是通用 IFactory 的实现,用于解决问题,而无需诉诸 ServiceLocator 反模式。
首先,您定义一个漂亮的通用工厂接口
,并定义使用 ninject 内核来创建请求的对象的实现,
使用以下命令绑定到您的工厂
现在您可以在控制器中执行以下操作。
在你的DomainBL中
Here's an implementation of a generic IFactory to solve the problem without resorting to the ServiceLocator anti-pattern.
First you define a nice generic factory interface
And define the implementation which uses ninject kernel to create the objects requested
Binding to your factory using the following
You can now do the following in your controller.
And in your DomainBL