我正在使用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工作正常,但另一个说:
没有为此对象定义无参数构造函数。
为什么?
提前致谢!吉列尔莫。
答案 0 :(得分: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[] { };
}
}
ControllerInstaller
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
但这两个类似乎共享相同的代码。
最诚挚的问候。吉列尔莫。
答案 1 :(得分:0)
如果有人仍然遇到此问题,解决方案是从System.Web.Http.Dependencies或System.Web.Mvc实现正确的IDependencyResolver接口。
请参阅https://stackoverflow.com/a/21459761以获取答案。