C# 稍微复杂的对象贴图
我有一个演示者来处理我表格的行为,比如:C# 稍微复杂的对象贴图,c#,winforms,ninject,inversion-of-control,mvp,C#,Winforms,Ninject,Inversion Of Control,Mvp,我有一个演示者来处理我表格的行为,比如: public class Form1Presenter { IForm1View _view; IUnitOfWork _unitOfWork; IService1 _service1; IService2 _service; public Form1Presenter( IForm1View view, IUnitOfWork unitOfWork, IServi
public class Form1Presenter
{
IForm1View _view;
IUnitOfWork _unitOfWork;
IService1 _service1;
IService2 _service;
public Form1Presenter(
IForm1View view,
IUnitOfWork unitOfWork,
IService1 service1,
IService2 service2)
{
_view = view;
_unitOfWork = unitOfWork;
_service1 = service1;
_service2 = service2;
}
}
public class Form1 : Form, IForm1View
{
public Form1()
{
IUnitOfWork unitOfWork = new UnitOfWork();
IService1 service1 = new Service1(unitOfWork);
IService1 service2 = new Service2(unitOfWork);
Form1Presenter presenter = new Form1Presenter(this, unitOfWork, service1, service2);
}
}
这些服务注入的工作单元对象与注入上述演示者的工作单元对象相同。像这样:
public class Service1 : IService1
{
IUnitOfWork _unitOfWork;
public Service1(IUnitOfWork unitOfWork)
{
_unitOfWork = unitOfWork;
}
}
要手动创建Form1Presenter,我必须执行以下操作:
public class Form1Presenter
{
IForm1View _view;
IUnitOfWork _unitOfWork;
IService1 _service1;
IService2 _service;
public Form1Presenter(
IForm1View view,
IUnitOfWork unitOfWork,
IService1 service1,
IService2 service2)
{
_view = view;
_unitOfWork = unitOfWork;
_service1 = service1;
_service2 = service2;
}
}
public class Form1 : Form, IForm1View
{
public Form1()
{
IUnitOfWork unitOfWork = new UnitOfWork();
IService1 service1 = new Service1(unitOfWork);
IService1 service2 = new Service2(unitOfWork);
Form1Presenter presenter = new Form1Presenter(this, unitOfWork, service1, service2);
}
}
有没有一个很好的方法来处理Ninject?我是新手,似乎无法解决这个问题。安装后,您可以将所有类绑定到它们的默认接口(前面有一个“I”的类名),如下所示
IKernel kernel = new StandardKernel();
kernel.Bind(x =>
x.FromThisAssembly() // Scans currently assembly
.IncludingNonePublicTypes() // Including Non-public types
.SelectAllClasses() // Retrieve all non-abstract classes
.BindDefaultInterface()); // Binds the default interface to them, e.g. class name without preceding "I"
var Form1Presenter = kernel.Get<Form1Presenter>();
IKernel内核=新的标准内核();
Bind(x=>
x、 FromThisAssembly()//扫描当前程序集
.IncludingNonePublicTypes()//包括非公共类型
.SelectAllClasses()//检索所有非抽象类
.BindDefaultInterface());//将默认接口绑定到它们,例如,没有前面的“I”的类名
var Form1Presenter=kernel.Get();
因此您希望为每个表单创建一个工作单元。我不想讨论这是否是一个明智的选择
有几种方法可以实现这一点:
1-手动管理
这将导致与DefinesNamedScope
绑定的所有对象及其所有依赖项获得相同的IUnitOfWork
实例。
但是,如果不在正确的范围内,则永远无法实例化i工作单元。因此,所有表单都需要定义一个(相同的)范围。另外,一个表单可能不依赖于另一个表单,因为这样会有范围重叠
3呼叫范围
InCallScope()
意味着由一个IResolutionRoot.Get()创建的所有对象将接收相同的对象
IBindingRoot.Bind<IUnitOfWork>().To<UnitOfWork>()
.InCallScope();
IBindingRoot.Bind()到()
.InCallScope();
不需要调整所有其他组件的绑定
如果一次调用IResolutionRoot.Get()
当然,还有更多的方法可以管理工作单元的生命周期。
我们已将会话管理与IUnitOfWork分离,并使用ThreadLocal
来确定是否需要启动新会话/事务或使用现有会话/事务。您必须使用作用域来确保服务1
,service2
和Form1Presenter
被注入相同的IUnitOfWork
实例。另外,您的I工作单元的生命周期(管理)是什么?是的,范围听起来像是我需要的东西。将为每个表单创建一个新的IUnitOfWork实例。。如果我在编写网页代码,我会使用InRequestScope。激活块似乎可以做到这一点,但它污染了我的代码,我希望将其限制在合成根目录中的Ninject细节。不要(永远)使用ActivationBlock
,它将从Ninject中删除,并有一些其他副作用,使事情复杂化。感谢您对ActivationBlock的指导。就像我说的,我是Ninject的新手。InCallScope()听起来很有希望,今天晚些时候我会尝试一下,如果一切顺利,我会将你的答案标记为接受。非常感谢。