首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >ArgumentNullException in WindsorControllerActivator

ArgumentNullException in WindsorControllerActivator
EN

Stack Overflow用户
提问于 2016-10-20 20:10:26
回答 1查看 105关注 0票数 0

我有一个具有多层(程序集)的项目。我使用城堡温莎解决依赖注入问题。还可以用城堡创建我的控制器。因此,我也在WebUI和WebUI层中安装和使用了城堡。此外,我还有一个引导程序层,它注册了所有服务和存储库。

首先我的web:

在WebApiConfig.cs文件中,我用流动的代码注册了UI依赖项:

代码语言:javascript
复制
public static void Register(HttpConfiguration config)
    {

        var corsAttr = new EnableCorsAttribute("*", "*", "*");
        config.EnableCors(corsAttr);

        // Web API configuration and services
        var container = Bootstrapper.WireUp();// to register services and repositories
        RegisterControllers(container);
        config.Services.Replace(typeof(IHttpControllerActivator), new WindsorControllerActivator(container));

    }

    private static void RegisterControllers(IWindsorContainer container)
    {
        //container.Register(Component.For<VisitorController>().LifestylePerWebRequest());
        //container.Register(Component.For<ValueController>().LifestylePerWebRequest());
        //container.Register(Component.For<ValidateController>().LifestylePerWebRequest());
        //container.Register(Component.For<CaptchaImageController>().LifestylePerWebRequest());
        container.Register(Classes.FromAssemblyContaining<VisitorController>()
            .BasedOn<ApiController>().LifestyleTransient());
    }

活化剂工厂是这样的:

代码语言:javascript
复制
 public class WindsorControllerActivator : IHttpControllerActivator
{
    private readonly IWindsorContainer _container;
    public WindsorControllerActivator(IWindsorContainer container)
    {
        _container = container;
    }

    public IHttpController Create(HttpRequestMessage request, HttpControllerDescriptor controllerDescriptor, Type controllerType)
    {
        return (IHttpController)_container.Resolve(controllerType);//System.ArgumentNullException: Value cannot be null. error
    }
}

在WebUI项目中,我还使用城堡温莎来创建控制器。但是当我运行该项目时,我得到的"System.ArgumentNullException:值不能为null.“当我正在解析控制器时出错,我的意思是在这一行:

代码语言:javascript
复制
(IHttpController)_container.Resolve(controllerType);

我还为我的控制器尝试了"LifeStylePerWebRequest“,没有任何改变。

更重要的是,WireUp方法没有什么问题(注册服务和存储库很好)。这个问题仅适用于控制器(在WebUI和WebApi项目中)。WebUI项目也会出现同样的问题。

EN

回答 1

Stack Overflow用户

发布于 2016-10-21 07:48:03

我通常使用IDependencyResolver的实现而不是IHttpControllerActivator。你可以用这种方法代替。添加浮动级:

代码语言:javascript
复制
public class WindsorDependencyResolver : IDependencyResolver
{
    readonly IWindsorContainer _container;

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

        _container = container;
    }

    public IDependencyScope BeginScope()
    {
        return new WindsorDependencyScope(this, _container.Release);
    }

    public void Dispose()
    {
    }

    public object GetService(Type t)
    {
        var ret = _container.Kernel.HasComponent(t) ? _container.Resolve(t) : null;
        return ret;
    }

    public IEnumerable<object> GetServices(Type t)
    {
        var ret = _container.ResolveAll(t).Cast<object>().ToArray();
        return ret;
    }
}

依赖项解析器需要此类:

代码语言:javascript
复制
public class WindsorDependencyScope : IDependencyScope
    {
        readonly List<object> _instances;
        readonly Action<object> _release;
        readonly IDependencyScope _scope;

        public WindsorDependencyScope(IDependencyScope scope, Action<object> release)
        {
            if (scope == null)
            {
                throw new ArgumentNullException(nameof(scope));
            }

            if (release == null)
            {
                throw new ArgumentNullException(nameof(release));
            }

            _scope = scope;
            _release = release;
            _instances = new List<object>();
        }

        public void Dispose()
        {
            foreach (object instance in _instances)
            {
                _release(instance);
            }

            _instances.Clear();
        }

        public object GetService(Type t)
        {
            var service = _scope.GetService(t);
            AddToScope(service);

            return service;
        }

        public IEnumerable<object> GetServices(Type t)
        {
            var services = _scope.GetServices(t);
            AddToScope(services);

            return services;
        }

        void AddToScope(params object[] services)
        {
            if (services.Any())
            {
                _instances.AddRange(services);
            }
        }
    }

这就是如何在Register方法中注册依赖项解析器:

代码语言:javascript
复制
config.DependencyResolver = new WindsorDependencyResolver(container);

我建议在依赖解析器负责处理这些控制器时,使用瞬态的生活方式注册控制器。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/40163653

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档