P.B*_*key 3 c# inversion-of-control asp.net-mvc-3
我正在设计一个允许我模拟我的数据库的设计,以便我可以测试我的观点.我不想阅读关于IOC的完整书籍,因为我现在没有时间.所以,这是我的家常菜.
控制器:
Run Code Online (Sandbox Code Playgroud)public ActionResult Milestone() { var result = SJMServiceFactory.GetService("Milestone"); return View(result); }
厂:
public static class SJMServiceFactory
{
public static DatabaseCollection_Result<T> GetService(string serviceName)
{
switch(serviceName)
{
case("Milestone"): return MileStoneService.GetMilestone();
case ("MilestoneMock"): return MileStoneService.GetMilestone(true);
default : return default(T);
}
}
}
Run Code Online (Sandbox Code Playgroud)
里程碑
public class MileStoneService
{
public MileStoneService()
{
}
public static DatabaseCollection_Result<Milestone> GetMilestone(bool Mock)
{
if (Mock)
{
DatabaseCollection_Result<Milestone> mileStones = new DatabaseCollection_Result<Milestone>();
Milestone milestone1 = new Milestone();
milestone1.Name = "New";
Milestone milestone2 = new Milestone();
milestone2.Name = "Assessment";
mileStones.Results.Add(milestone1);
mileStones.Results.Add(milestone2);
return mileStones;
}
else
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
我想我需要从我的工厂返回一个接口,而不是我试过的那种Generic类型.我不知道如何创建一个适用于我所有模型的界面,是错误的方向吗?
没有阅读整本书(是否存在一个?IoC在事物计划中是一个非常小的主题):
控制器:
private readonly IMilestoneService milestoneSerivce;
public MilestoneController(IMilestoneService milestoneService)
{
this.milestoneService = milestoneService;
}
public ActionResult Milestone()
{
var result = milestoneService.GetMilestones();
return View(result);
}
Run Code Online (Sandbox Code Playgroud)
IMilestoneService.cs
public interface IMilestoneService
{
DatabaseCollection_Result<Milestone> GetMilestones();
}
Run Code Online (Sandbox Code Playgroud)
MilestoneService.cs
public class MilestoneService : IMilestoneService
{
public DatabaseCollection_Result<Milestone> GetMilestones()
{
return null;
}
}
Run Code Online (Sandbox Code Playgroud)
MockMilestoneService.cs:
public class MockMilestoneService : IMilestoneService
{
public DatabaseCollection_Result<Milestone> GetMilestones()
{
DatabaseCollection_Result<Milestone> mileStones = new DatabaseCollection_Result<Milestone>();
Milestone milestone1 = new Milestone();
milestone1.Name = "New";
Milestone milestone2 = new Milestone();
milestone2.Name = "Assessment";
mileStones.Results.Add(milestone1);
mileStones.Results.Add(milestone2);
return mileStones;
}
}
Run Code Online (Sandbox Code Playgroud)
Global.asax中:
ObjectFactory.Configure(x => {
x.For<IMilestoneService>().Use<MilestoneService>();
// uncomment for test
//x.For<IMilestoneService>().Use<MockMilestoneService>();
});
Run Code Online (Sandbox Code Playgroud)
这使用了StructureMap,但我想Ninject连接依赖关系的方法是类似的.从来没有使用Ninject我不确定,但看起来它可能是这样的:
Bind<IMilestoneService>().To<MilestoneService>();
Run Code Online (Sandbox Code Playgroud)
一般来说,虽然我不打算创建一个全新的类来测试你的视图,但是我会使用一个模拟框架(如Moq)来创建模拟对象并将它们传递给View,然后使用关于ViewResult的Assertions来确定它是否有效正确.
如果您正在进行交互式测试并希望与数据库分离,这可能是一种正常的方法.
不要害怕学习曲线.IoC是一个相当简单的概念.
Ninject是我收集的第一个容器,它顺利进行.在任何时候我真正努力的唯一一点是如何组织所有绑定,但即使这只是大型应用程序中的一个问题.
YMMV,但我想说只是潜入Ninject或类似的是比DIY更好的时间投入.
使用Ninject的IoC仅在几个地方使用代码.
1:将接口绑定到实现:
public class ServiceModule : NinjectModule
{
public override void Load() {
Bind<Common.Billing.AuthorizeNet.IBillingGatewayParametersFactory>().To<AuthorizeNetParameterFactory>();
Bind<Common.Billing.IBillingGateway>().To<Common.Billing.AuthorizeNet.BillingGateway>();
}
}
Run Code Online (Sandbox Code Playgroud)
2:使用构造函数参数将依赖项传递给类:
public class BillPayingService
{
private readonly IBillingGateway _billingGateway;
public BillPayingService(
IBillingGateway billingGateway
)
{
_billingGateway = billingGateway;
}
public void PayBills()
{
// ....
}
}
Run Code Online (Sandbox Code Playgroud)
3:在应用程序启动时初始化容器:
public static class Ioc
{
public static void Initialize()
{
var modules = new INinjectModule[] {
new ServicesModule(),
new DataModule()
new VideoProcessing.NinjectModule()
};
IKernel kernel = new Ninject.StandardKernel(modules);
}
}
Run Code Online (Sandbox Code Playgroud)