我正在看看ASP.NET MVC 4 RC,並且找不到DefaultHttpControllerFactory,甚至找不到IHttpControllerFactory來允許我選擇的IoC容器(Castle Windsor)掛鉤到Web Api框架中控制器。我最終使用了IDependencyResolver,這使得發佈組件變得有點棘手,但最終以下列結果。在IDependencyResolver有一個Release方法之前它會工作/不是內存泄漏嗎? Global.asax中結束爲:ASP.NET MVC 4 RC與Castle Windsor
public class WebApiApplication : System.Web.HttpApplication
{
private IWindsorContainer container;
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
Windsor();
}
protected void Application_End()
{
container.Dispose();
}
private void Windsor()
{
container = new WindsorContainer().Install(FromAssembly.This());
// mvc:
var mvcControllerFactory = new WindsorControllerFactory(container.Kernel);
ControllerBuilder.Current.SetControllerFactory(mvcControllerFactory);
// web api:
var httpDependencyResolver = new WindsorHttpDependencyResolver(container.Kernel);
GlobalConfiguration.Configuration.DependencyResolver = httpDependencyResolver;
}
}
WindsorControllerFactory是DefaultControllerFactory的擴展MVC控制器並有溫莎安裝它們。 WindsorHttpDependencyResolver結束爲:
public class WindsorHttpDependencyResolver : System.Web.Http.Dependencies.IDependencyResolver
{
private readonly IKernel kernel;
public WindsorHttpDependencyResolver(IKernel kernel)
{
this.kernel = kernel;
}
public IDependencyScope BeginScope()
{
return kernel.Resolve<IDependencyScope>(); // instances released suitably (at end of web request)
}
public object GetService(Type serviceType)
{
// for ModelMetadataProvider and other MVC related types that may have been added to the container
// check the lifecycle of these registrations
return kernel.HasComponent(serviceType) ? kernel.Resolve(serviceType) : null;
}
public IEnumerable<object> GetServices(Type serviceType)
{
return kernel.HasComponent(serviceType) ? kernel.ResolveAll(serviceType) as IEnumerable<object> : Enumerable.Empty<object>();
}
public void Dispose()
{
// Nothing created so nothing to dispose - kernel will take care of its own
}
}
從理論上講,這意味着現在溫莎將提供API的控制器,一旦被安裝:
public class ApiControllersInstaller : IWindsorInstaller
{
public void Install(IWindsorContainer container, IConfigurationStore store)
{
container.AddFacility<TypedFactoryFacility>();
container.Register(Component.For<ITypedFactoryComponentSelector>().ImplementedBy<WebApiTypedFactoryComponentSelector>());
container.Register(Component.For<IDependencyScope>().AsFactory(tfc => tfc.SelectedWith<WebApiTypedFactoryComponentSelector>()).LifestylePerWebRequest());
container.Register(Classes.FromAssemblyContaining<ValuesController>().BasedOn<IHttpController>().LifestyleTransient());
}
}
我使用的是類型化的工廠設施,以實現IDependencyScope我,這意味着當框架在請求的末尾處理它時,它將隱含地釋放控制器及其依賴關係。通過使用Per Web Request生命週期,Windsor也將釋放工廠本身。這只是葉自定義類型工廠組件選擇作爲GetService的(一個或多個)容器不會找到任何東西:
public class WebApiTypedFactoryComponentSelector : DefaultTypedFactoryComponentSelector
{
protected override string GetComponentName(System.Reflection.MethodInfo method, object[] arguments)
{
if (method.Name == "GetService" || method.Name == "GetServices")
{
return (arguments[0] as Type).FullName;
}
return base.GetComponentName(method, arguments);
}
protected override Type GetComponentType(System.Reflection.MethodInfo method, object[] arguments)
{
if (method.Name == "GetService" || method.Name == "GetServices")
{
return arguments[0] as Type;
}
return base.GetComponentType(method, arguments);
}
}
希望這是非常有用的。
是你的問題「它是否會工作/內存泄漏,直到IDependencyResolver有一個發佈方法?」? – 2012-07-24 21:41:47
@Jesse我想我試圖找出這是否是一個可行的方法給予MVC 4 RC的結構。我想我已經正確理解了Windsor文檔,但是如果我在某處犯了錯誤,如果有人指出它會很感激。 – hagrid27 2012-07-24 22:00:35