ASP.NET MVC 4 RC与温莎城堡 [英] ASP.NET MVC 4 RC with Castle Windsor

查看:147
本文介绍了ASP.NET MVC 4 RC与温莎城堡的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在看一下ASP.NET MVC 4 RC并不能找到DefaultHttpControllerFactory甚至IHttpControllerFactory让我选择的IoC容器(温莎城堡)挂接到的网页API控制器的框架。最后我用的IDependencyResolver这使得释放组件有点麻烦,但最终与下面。难道是去工作/没有内存泄漏,直到的IDependencyResolver有一个释放的方法?
Global.asax中最终为:

I was taking a look at ASP.NET MVC 4 RC and cannot find DefaultHttpControllerFactory or even IHttpControllerFactory to allow my IoC container of choice (Castle Windsor) to hook into the framework for Web Api controllers. I ended up using IDependencyResolver which makes releasing components a bit trickier, but ended up with the following. Is it going to work / not memory leak until IDependencyResolver has a Release method? Global.asax ends up as:

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最终为:

WindsorControllerFactory is extension of DefaultControllerFactory for Mvc Controllers and there is a Windsor installer for them. WindsorHttpDependencyResolver ends up as:

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的控制器,一旦被安装:

Theoretically, this means Windsor will now provide the Api Controllers, once they are installed:

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对我来说,当框架在请求结束处置它,这意味着,它会释放控制器及其隐含的依赖。通过使用每个Web请求的生命周期,温莎将发布工厂本身了。刚刚离开的自定义类型工厂组件选择作为GetService的(S)将无法找到在容器什么:

I'm using the typed factory facility to implement IDependencyScope for me, which means when the framework disposes it at the end of a request, it will release the controller and its dependencies implicitly. By using a Per Web Request life cycle, Windsor will release the factory itself too. That just leaves the custom typed factory component selector as GetService(s) will not find anything in the container:

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);
    }
}

希望这是非常有用的。

Hope this is useful.

推荐答案

我最终使用code从<一个href=\"http://nikosbaxevanis.com/2012/06/04/using-the-web-api-dependency-resolver-with-castle-windsor-part-2/\"相对=nofollow>这个博客帖子(由这等之一马克西曼),其中每个请求创建一个范围,并采取释放创建的对象的照顾。这是一个稍微不同的方式对你已经采取了的。

I ended up using code from this blog post (further enhanced by this other one by Mark Seemann), which creates a scope per request and takes care of releasing the created objects. This is a slightly different approach to the one you've taken.

这篇关于ASP.NET MVC 4 RC与温莎城堡的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆