asp.net-mvc – 使用Castle Windsor在ASP.NET MVC中设置控制反转(IoC)

我正在讨论Sanderson的Pro ASP.NET MVC框架,在第4章他讨论了 Creating a Custom Controller Factory,看来用于注册控制器的原始方法AddComponentLifeStyle或AddComponentWithLifeStyle现在已被弃用:
public class WindsorControllerFactory : DefaultControllerFactory
{
    IWindsorContainer container;

    public WindsorControllerFactory()
    {
        container = new WindsorContainer(new XmlInterpreter(new ConfigResource("castle")));

        // register all the controller types as transient
        var controllerTypes = from t in Assembly.GetExecutingAssembly().GetTypes()
                              where typeof(IController).IsAssignableFrom(t)
                              select t;

        //[Obsolete("Use Register(Component.For<I>().ImplementedBy<T>().Named(key).Lifestyle.Is(lifestyle)) instead.")]
        //IWindsorContainer AddComponentLifeStyle<I,T>(string key,LifestyleType lifestyle) where T : class;
        foreach (Type t in controllerTypes)
        {
            container.Register(Component.For<IController>().ImplementedBy<???>().Named(t.FullName).LifeStyle.Is(LifestyleType.Transient));
        }
    }

    // Constructs the controller instance needed to service each request
    protected override IController GetControllerInstance(Type controllerType)
    {
        return (IController)container.Resolve(controllerType);
    }
}

新的建议是使用Register(Component.For< I>().ImplementedBy< T>().Named(key).Lifestyle.Is(lifestyle)),但我无法弄清楚如何呈现实现控制器输入ImplementedBy< ???>()方法.我尝试了ImplementedBy< t>()和ImplementedBy< typeof(t)>(),但我找不到传递实现类型的适当方法.有任何想法吗?

解决方法

我正在使用 ControllerBuilder.SetControllerFactory以及您可以在开源项目 MvcContrib中找到的代码执行此操作:

的Global.asax.cs

protected void Application_Start()
{
    ...

    IWindsorContainer windsorContainer = new WindsorContainer();
    windsorContainer.RegisterControllers(Assembly.GetExecutingAssembly());
    ControllerBuilder.Current.SetControllerFactory(new WindsorControllerFactory(windsorContainer));

    ...
}

WindsorControllerFactory

public class WindsorControllerFactory : DefaultControllerFactory
{
    private readonly IWindsorContainer _container;

    public WindsorControllerFactory(IWindsorContainer container)
    {
        if (container == null)
        {
            throw new ArgumentNullException();
        }

        _container = container;
    }

    protected override IController GetControllerInstance(RequestContext requestContext,Type controllerType)
    {
        if (controllerType == null)
        {
            throw new HttpException();
        }

        if (!typeof(IController).IsAssignableFrom(controllerType))
        {
            throw new ArgumentException();
        }

        try
        {
            return (IController)_container.Resolve(controllerType);
        }
        catch (Exception ex)
        {
            throw new InvalidOperationException();
        }
    }

    public override void ReleaseController(IController controller)
    {
        Idisposable disposable = controller as Idisposable;

        if (disposable != null)
        {
            disposable.dispose();
        }

        _container.Release(controller);
    }
}

WindsorExtensions(见MvcContrib)

public static class WindsorExtensions
{
    public static IWindsorContainer RegisterController<T>(this IWindsorContainer container) where T : IController
    {
        container.RegisterControllers(typeof(T));

        return container;
    }

    public static IWindsorContainer RegisterControllers(this IWindsorContainer container,params Type[] controllerTypes)
    {
        foreach (Type type in controllerTypes)
        {
            if (ControllerExtensions.IsController(type))
            {
                container.Register(Component.For(type).Named(type.FullName).LifeStyle.Is(LifestyleType.Transient));
            }
        }

        return container;
    }

    public static IWindsorContainer RegisterControllers(this IWindsorContainer container,params Assembly[] assemblies)
    {
        foreach (Assembly assembly in assemblies)
        {
            container.RegisterControllers(assembly.GetExportedTypes());
        }

        return container;
    }
}

ControllerExtensions(见MvcContrib)

public static class ControllerExtensions
{
    public static bool IsController(Type type)
    {
        return type != null
               && type.Name.EndsWith("Controller",StringComparison.OrdinalIgnoreCase)
               && !type.IsAbstract
               && typeof(IController).IsAssignableFrom(type);
    }
}

相关文章

### 创建一个gRPC服务项目(grpc服务端)和一个 webapi项目(...
一、SiganlR 使用的协议类型 1.websocket即时通讯协议 2.Ser...
.Net 6 WebApi 项目 在Linux系统上 打包成Docker镜像,发布为...
一、 PD简介PowerDesigner 是一个集所有现代建模技术于一身的...
一、存储过程 存储过程就像数据库中运行的方法(函数) 优点:...
一、Ueditor的下载 1、百度编辑器下载地址:http://ueditor....