0

我正在一个项目中使用 ApiControllers 和 Controllers(不是 webapi)和 Castle(来自 Nuget)

 internal class WebWindsorInstaller : IWindsorInstaller
    {
        public void Install(IWindsorContainer container, IConfigurationStore store)
        {
            container.Register(Component
                .For<RepositoryFactories>()
                .ImplementedBy<RepositoryFactories>()
                .LifestyleSingleton());

            container.Register(Component
                .For<IRepositoryProvider>()
                .ImplementedBy<RepositoryProvider>()
                .LifestylePerWebRequest());

            container.Register(Component
                .For<IProjUow>()
                .ImplementedBy<ProjUow>()
                .LifestylePerWebRequest());

            container.Register(Classes
                .FromAssemblyContaining<Api.CategoriesController>()
                .BasedOn<IHttpController>()
                .If(t => t.Name.EndsWith("Controller"))
                .LifestylePerWebRequest());

            container.Register(Classes
                .FromAssemblyContaining<CategoriesController>()
                .BasedOn<IController>()
                .If(t => t.Name.EndsWith("Controller"))
                .LifestylePerWebRequest());
        }
    }

这在 global.asax (Application_Start)

var container = new WindsorContainer().Install(new WebWindsorInstaller());
GlobalConfiguration.Configuration.DependencyResolver = new WindsorDependencyResolver(container);

这是 CategoriesController 的 Controller 构造函数

public class CategoriesController : ControllerBase
{
    public CategoriesController(IProjUow uow)
    {
        Uow = uow;
    }
}

而ControllerBase继承自Controller

ApiController 定义如下:

public abstract class ApiControllerBase : ApiController
{
    protected IProjUow Uow { get; set; }
}

public class CategoriesController : ApiControllerBase
{
    public CategoriesController(IProjUow uow)
    {
        Uow = uow;
    }
}

ApiController 工作正常,但另一个说:

没有为此对象定义无参数构造函数。

为什么?

提前致谢!吉列尔莫。

4

2 回答 2

0

好的,菲尔的链接为我指明了正确的方向。如果有人遇到同样的问题,我会分享我的解决方案。

这应该在 Global.asax.cx 中(Application_Start 方法)

// Set the dependency resolver for Web API.
var webApicontainer = new WindsorContainer().Install(new WebWindsorInstaller());
GlobalConfiguration.Configuration.DependencyResolver = new WebApiWindsorDependencyResolver(webApicontainer);

// Set the dependency resolver for Mvc Controllers
Container = new WindsorContainer()
    .Install(new ControllersInstaller());
DependencyResolver.SetResolver(new MvcWindsorDependencyResolver(Container)); 
ServiceLocator.SetLocatorProvider(() => new WindsorServiceLocator(Container)); 
var controllerFactory = new WindsorControllerFactory(Container.Kernel); 
ControllerBuilder.Current.SetControllerFactory(controllerFactory); 

WebApiWindsorDependecyResolver

 internal class WebApiWindsorDependencyResolver : IDependencyResolver
    {
        private readonly IWindsorContainer container;

        public WebApiWindsorDependencyResolver(IWindsorContainer container)
        {
            if (container == null) { throw new ArgumentNullException("container"); }
            this.container = container;
        }

        public object GetService(Type t)
        {
            return this.container.Kernel.HasComponent(t) ? this.container.Resolve(t) : null;
        }

        public IEnumerable<object> GetServices(Type t)
        {
            return this.container.ResolveAll(t).Cast<object>().ToArray();
        }

        public IDependencyScope BeginScope()
        {
            return new ReleasingDependencyScope(this as IDependencyScope, this.container.Release);
        }

        public void Dispose()
        {
        }
    }

MvcWindsorDependencyResolver

 internal class MvcWindsorDependencyResolver : IDependencyResolver
    {
        private readonly IWindsorContainer container;

        public MvcWindsorDependencyResolver(IWindsorContainer container)
        {
            this.container = container;
        }

        public object GetService(Type serviceType)
        {
            return container.Kernel.HasComponent(serviceType) ? container.Resolve(serviceType) : null;
        }

        public IEnumerable<object> GetServices(Type serviceType)
        {
            return container.Kernel.HasComponent(serviceType) ? container.ResolveAll(serviceType).Cast<object>() : new object[] { };
        }
    }

控制器安装程序

public class ControllersInstaller : IWindsorInstaller
    {
        public void Install(IWindsorContainer container, IConfigurationStore store)
        {
            container.Register(FindControllers().Configure(c => c.LifestyleTransient()));

            container.Register(Component
                .For<RepositoryFactories>()
                .ImplementedBy<RepositoryFactories>()
                .LifestyleSingleton());

            container.Register(Component
                .For<IRepositoryProvider>()
                .ImplementedBy<RepositoryProvider>()
                .LifestylePerWebRequest());

            container.Register(Component
                .For<IProjUow>()
                .ImplementedBy<ProjUow>()
                .LifestylePerWebRequest());
        }

        private static BasedOnDescriptor FindControllers()
        {

            return AllTypes.FromThisAssembly()
                .BasedOn<IController>()
                .If(t => t.Name.EndsWith("Controller"));
        }
    }

WebWindsorInstaller

 internal class WebWindsorInstaller : IWindsorInstaller
    {
        public void Install(IWindsorContainer container, IConfigurationStore store)
        {
            container.Register(Component
                .For<RepositoryFactories>()
                .ImplementedBy<RepositoryFactories>()
                .LifestyleSingleton());

            container.Register(Component
                .For<IRepositoryProvider>()
                .ImplementedBy<RepositoryProvider>()
                .LifestylePerWebRequest());

            container.Register(Component
                .For<IProjUow>()
                .ImplementedBy<ProjUow>()
                .LifestylePerWebRequest());

            container.Register(Classes
                .FromAssemblyContaining<Api.CategoriesController>()
                .BasedOn<IHttpController>()
                .If(t => t.Name.EndsWith("Controller"))
                .LifestylePerWebRequest());
        }
    }

唯一我不太了解的事情(尽管这有效)是为什么我需要有两个类 DependencyResolver(WebApiWindsorDependencyResolver 和 MvcWindsorDependencyResolver)当它们几乎相同时。我可以摆脱其中之一吗?

如果我更改代码而不是

DependencyResolver.SetResolver(new MvcWindsorDependencyResolver(Container)); 

我写

DependencyResolver.SetResolver(new WebApiWindsorDependencyResolver(Container)); 

它说

The type Proj.UI.Cms.Infrastructure.WebApiWindsorDependencyResolver does not appear to implement Microsoft.Practices.ServiceLocation.IServiceLocator.
Parameter name: commonServiceLocator

但是这两个类似乎共享相同的代码。

最好的祝福。吉列尔莫。

于 2012-11-23T13:58:19.287 回答
0

如果有人仍然遇到这个问题,解决方案是从 System.Web.Http.Dependencies 或 System.Web.Mvc 实现正确的 IDependencyResolver 接口。

有关答案,请参阅https://stackoverflow.com/a/21459761

于 2014-12-16T16:09:40.710 回答