den*_*s_n 7 asp.net asp.net-mvc mef
我想在asp.net mvc中使用MEF.我写了以下控制器工厂:
public class MefControllerFactory : DefaultControllerFactory
{
private CompositionContainer _Container;
public MefControllerFactory(Assembly assembly)
{
_Container = new CompositionContainer(new AssemblyCatalog(assembly));
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType != null)
{
var controllers = _Container.GetExports<IController>();
var controllerExport = controllers.Where(x => x.Value.GetType() == controllerType).FirstOrDefault();
if (controllerExport == null)
{
return base.GetControllerInstance(requestContext, controllerType);
}
return controllerExport.Value;
}
else
{
throw new HttpException((Int32)HttpStatusCode.NotFound,
String.Format(
"The controller for path '{0}' could not be found or it does not implement IController.",
requestContext.HttpContext.Request.Path
)
);
}
}
}
Run Code Online (Sandbox Code Playgroud)
在Global.asax.cs我正在设置我的控制器工厂:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
RegisterRoutes(RouteTable.Routes);
ControllerBuilder.Current.SetControllerFactory(new MefControllerFactory.MefControllerFactory(Assembly.GetExecutingAssembly()));
}
Run Code Online (Sandbox Code Playgroud)
我有一个区域:
[Export(typeof(IController))]
[PartCreationPolicy(CreationPolicy.NonShared)]
public class HomeController : Controller
{
private readonly IArticleService _articleService;
[ImportingConstructor]
public HomeController(IArticleService articleService)
{
_articleService = articleService;
}
//
// GET: /Articles/Home/
public ActionResult Index()
{
Article article = _articleService.GetById(55);
return View(article);
}
}
Run Code Online (Sandbox Code Playgroud)
IArticleService 是一个界面.
有一个实现IArticleService和导出它的类.
有用.
这就是我使用MEF所需要的一切吗?
如何跳过设置PartCreationPolicy和ImportingConstructor控制器?
我想使用构造函数设置我的依赖项.
什么时候PartCreationPolicy丢失,我得到以下异常:
控制器'MvcApplication4.Areas.Articles.Controllers.HomeController'的单个实例不能用于处理多个请求.如果正在使用自定义控制器工厂,请确保它为每个请求创建控制器的新实例.
我决定回到Unity。
我创建了一个自定义属性而不是 MEF 的 ExportAttribute
[AttributeUsage(AttributeTargets.Class, AllowMultiple = false, Inherited = false)]
public class ImplementsAttribute : Attribute
{
public ImplementsAttribute(Type contractType)
{
ContractType = contractType;
}
public Type ContractType
{
get;
private set;
}
}
Run Code Online (Sandbox Code Playgroud)
例子:
[Implements(typeof(ICustomerEmailService))]
public class CustomerEmailService : ICustomerEmailService
{...}
Run Code Online (Sandbox Code Playgroud)
和一个自定义控制器工厂:
public class MyControllerFactory : DefaultControllerFactory
{
private readonly IUnityContainer _container;
public MyControllerFactory()
{
_container = new UnityContainer();
Func<Type, bool> isController =
(type) => typeof(IController).IsAssignableFrom(type)
&& (type.IsAbstract || type.IsInterface
|| type.GetCustomAttributes(typeof(GeneratedCodeAttribute), true).Any()) != true;
foreach (Assembly assembly in BuildManager.GetReferencedAssemblies())
{
try
{
var types = assembly.GetTypes();
// Also register all controllers
var controllerTypes = from t in types where isController(t)
select t;
foreach (Type t in controllerTypes)
{
_container.RegisterType(t);
}
// register all providers
var providers =
from t in types
from export in t.GetCustomAttributes(typeof(ImplementsAttribute), true).OfType<ImplementsAttribute>()
select new { export.ContractType, Provider = t };
foreach (var item in providers)
{
if (item.ContractType != null)
{
_container.RegisterType(item.ContractType, item.Provider);
}
else
{
_container.RegisterType(item.Provider);
}
}
}
catch
{
}
}
}
protected override IController GetControllerInstance(RequestContext requestContext, Type controllerType)
{
if (controllerType != null)
{
var controller = _container.Resolve(controllerType) as IController;
if (controller == null)
{
return base.GetControllerInstance(requestContext, controllerType);
}
return controller;
}
throw new HttpException((Int32)HttpStatusCode.NotFound,
String.Format(
"The controller for path '{0}' could not be found or it does not implement IController.",
requestContext.HttpContext.Request.Path)
);
}
}
Run Code Online (Sandbox Code Playgroud)
对我来说解决 MEF 控制器工厂的所有问题太困难了:(
| 归档时间: |
|
| 查看次数: |
4693 次 |
| 最近记录: |