C#、MVC、IoC、依赖注入
C#, MVC, IoC, Dependency Injection
这是我的 BaseController
:
using Ferrero.Data;
using System;
using System.Collections.Generic;
using System.Linq; using System.Web; using System.Web.Mvc;
namespace Ferrero.Web.Controllers
{
public abstract class BaseController : Controller
{
protected IFerreroUow Uow { get; set; }
public MasterLayoutView masterlayout = new MasterLayoutView();
}
}
这是我的 HomeController
继承自 BaseController
:
using Ferrero.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Ferrero.Model;
namespace Ferrero.Web.Controllers
{
public class HomeController : BaseController
{
public HomeController(IFerreroUow uow)
{
Uow = uow;
}
public ActionResult Index()
{
ViewBag.Title = "Home Page";
masterlayout.employees_list = Uow.Employees.GetAll().ToList();
return View();
}
}
}
Uow 是我拥有所有存储库的工作单元,我希望它在每个控制器中都可用。问题是我没有正确使用 Ioc,当我 运行 应用程序
时出现此错误
An error occurred when trying to create a controller of type 'Ferrero.Web.Controllers.HomeController'. Make sure that the controller has a parameterless public constructor.
有人能帮帮我吗?
有时您根本不需要容器 :) 您只需要知道 Composition Root。如何在不使用容器 AKA Pure DI 的情况下在 WebApi 和 MVC 中执行此操作的示例:
public interface ISingleton : IDisposable { }
public class TransientDependency { }
public class Singleton : ISingleton
{
public void Dispose() { }
}
// IHttpControllerActivator is for WebApi, IControllerFactory for MVC
public class CompositionRoot : IDisposable, IHttpControllerActivator, IControllerFactory
{
private readonly ISingleton _singleton;
// pass in any true singletons i.e. cross application instance singletons
public CompositionRoot()
{
// intitialise any application instance singletons
_singleton = new Singleton();
}
public void Dispose()
{
_singleton.Dispose();
}
// Web API
public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
{
// Per-Request-scoped services are declared and initialized here
if (controllerType == typeof(SomeApiController))
{
// Transient services are created and directly injected here
return new SomeApiController(_singleton, new TransientDependency());
}
var argumentException = new ArgumentException(@"Unexpected controller type! " + controllerType.Name,
nameof(controllerType));
Log.Error(argumentException, "don't know how to instantiate API controller: {controllerType}", controllerType.Name);
throw argumentException;
}
// MVC
public IController CreateController(RequestContext requestContext, string controllerName)
{
if (controllerName.ToLower() == "home")
{
return new HomeController(_singleton, new TransientDependency());
}
var argumentException = new ArgumentException(@"Unexpected controller! " + controllerName);
Log.Error("don't know how to instantiate MVC controller: {controllerType}. redirecting to help", controllerName);
throw argumentException; // Alternatively would return some default Page Not Found placeholder controller;
}
// MVC
public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName)
{
return SessionStateBehavior.Default;
}
// MVC
public void ReleaseController(IController controller)
{
// anything to clean up?
}
}
public static class DependencyInjection
{
public static void WireUp()
{
var compositionRoot = new CompositionRoot();
System.Web.Mvc.ControllerBuilder.Current.SetControllerFactory(compositionRoot);
System.Web.Http.GlobalConfiguration.Configuration.Services.Replace(typeof (IHttpControllerActivator), compositionRoot);
}
}
我找到了我的解决方案 here!!!感谢这个人!谁要实现Ninject到mvc这就是最好的例子。
这是我的 BaseController
:
using Ferrero.Data;
using System;
using System.Collections.Generic;
using System.Linq; using System.Web; using System.Web.Mvc;
namespace Ferrero.Web.Controllers
{
public abstract class BaseController : Controller
{
protected IFerreroUow Uow { get; set; }
public MasterLayoutView masterlayout = new MasterLayoutView();
}
}
这是我的 HomeController
继承自 BaseController
:
using Ferrero.Data;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using Ferrero.Model;
namespace Ferrero.Web.Controllers
{
public class HomeController : BaseController
{
public HomeController(IFerreroUow uow)
{
Uow = uow;
}
public ActionResult Index()
{
ViewBag.Title = "Home Page";
masterlayout.employees_list = Uow.Employees.GetAll().ToList();
return View();
}
}
}
Uow 是我拥有所有存储库的工作单元,我希望它在每个控制器中都可用。问题是我没有正确使用 Ioc,当我 运行 应用程序
时出现此错误An error occurred when trying to create a controller of type 'Ferrero.Web.Controllers.HomeController'. Make sure that the controller has a parameterless public constructor.
有人能帮帮我吗?
有时您根本不需要容器 :) 您只需要知道 Composition Root。如何在不使用容器 AKA Pure DI 的情况下在 WebApi 和 MVC 中执行此操作的示例:
public interface ISingleton : IDisposable { }
public class TransientDependency { }
public class Singleton : ISingleton
{
public void Dispose() { }
}
// IHttpControllerActivator is for WebApi, IControllerFactory for MVC
public class CompositionRoot : IDisposable, IHttpControllerActivator, IControllerFactory
{
private readonly ISingleton _singleton;
// pass in any true singletons i.e. cross application instance singletons
public CompositionRoot()
{
// intitialise any application instance singletons
_singleton = new Singleton();
}
public void Dispose()
{
_singleton.Dispose();
}
// Web API
public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
{
// Per-Request-scoped services are declared and initialized here
if (controllerType == typeof(SomeApiController))
{
// Transient services are created and directly injected here
return new SomeApiController(_singleton, new TransientDependency());
}
var argumentException = new ArgumentException(@"Unexpected controller type! " + controllerType.Name,
nameof(controllerType));
Log.Error(argumentException, "don't know how to instantiate API controller: {controllerType}", controllerType.Name);
throw argumentException;
}
// MVC
public IController CreateController(RequestContext requestContext, string controllerName)
{
if (controllerName.ToLower() == "home")
{
return new HomeController(_singleton, new TransientDependency());
}
var argumentException = new ArgumentException(@"Unexpected controller! " + controllerName);
Log.Error("don't know how to instantiate MVC controller: {controllerType}. redirecting to help", controllerName);
throw argumentException; // Alternatively would return some default Page Not Found placeholder controller;
}
// MVC
public SessionStateBehavior GetControllerSessionBehavior(RequestContext requestContext, string controllerName)
{
return SessionStateBehavior.Default;
}
// MVC
public void ReleaseController(IController controller)
{
// anything to clean up?
}
}
public static class DependencyInjection
{
public static void WireUp()
{
var compositionRoot = new CompositionRoot();
System.Web.Mvc.ControllerBuilder.Current.SetControllerFactory(compositionRoot);
System.Web.Http.GlobalConfiguration.Configuration.Services.Replace(typeof (IHttpControllerActivator), compositionRoot);
}
}
我找到了我的解决方案 here!!!感谢这个人!谁要实现Ninject到mvc这就是最好的例子。