繁体   English   中英

Castle Windsor ASP.NET MVC 4和Web API相同的应用程序。 只有MVC控制器没有依赖关系?

[英]Castle Windsor ASP.NET MVC 4 and Web API same application. Only if MVC controllers have no dependencies?

本文是使用Castle Windsor进行Web API的一个很好的起点,但是如果我创建一个简单的MVC控制器呢? 只有在注入没有依赖性时它才有效。

添加这个,即:

public class HomeController : Controller
{
    private readonly IValuesRepository repository;

    public HomeController(IValuesRepository repository)
    {
        this.repository = repository;
    }

    public ActionResult Index()
    {
        return View();
    }
}

导致以下错误:

为此对象定义的无参数构造函数

有没有办法在使用Castle Windsor的同一个应用程序中使用MVC和Web API逻辑?

application_start设置DependencyResolver.SetResolver(...)后,我没有注意到我的应用程序有任何改进。

如你看到的。

WebApiScopedLifetimeDependencyResolverSample.Windsor.WindsorDependencyResolver类型似乎没有实现

实现服务定位器:

internal sealed class WindsorDependencyResolver
    : ServiceLocatorImplBase, IDependencyResolver
{
    private readonly IWindsorContainer container;

    public WindsorDependencyResolver(
        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 WindsorDependencyScope(this.container);
    }

    public void Dispose()
    {
    }

    protected override object DoGetInstance(
        Type serviceType, string key)
    {
        if (key != null)
            return container.Resolve(key, serviceType);
        return container.Resolve(serviceType);
    }

    protected override IEnumerable<object> DoGetAllInstances(
        Type serviceType)
    {
        return (object[])container.ResolveAll(serviceType);
    }

把我带回了起点。

终于解决了。

这是其他人的解决方案


在application_start中......

//mvc
DependencyResolver.SetResolver(
    new WindsorMvcDependencyResolver(container));

// web api:
var httpDependencyResolver = 
    new WindsorHttpDependencyResolver(container);

GlobalConfiguration.Configuration.DependencyResolver =
    httpDependencyResolver;

internal class WindsorMvcDependencyResolver
    : WindsorDependencyScope, IDependencyResolver
{
    private readonly IWindsorContainer container;

    public WindsorMvcDependencyResolver(
        IWindsorContainer container) : base(container)
    {
        this.container = container;
    }
}


internal sealed class WindsorHttpDependencyResolver
    : IDependencyResolver
{
    private readonly IWindsorContainer container;

    public WindsorHttpDependencyResolver(
        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 WindsorDependencyScope(this.container);
    }

    public void Dispose()
    {
    }
}

internal class WindsorDependencyScope : IDependencyScope
{
    private readonly IWindsorContainer container;
    private readonly IDisposable scope;

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

        this.container = container;
        this.scope = container.BeginScope();
    }

    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 void Dispose()
    {
        this.scope.Dispose();
    }
}

并注册了mvc和web api控制器

container.Register(Classes
    .FromAssemblyContaining<HomeController>()
    .BasedOn<Controller>()
    .LifestylePerWebRequest());


container.Register(Classes
    .FromAssemblyContaining<ValuesController>()
    .BasedOn<IHttpController>()
    .LifestyleScoped());

Microsoft似乎推动将Web API放入与MVC应用程序相同的项目中(由他们使用的模板引起)。 但是,我不会将Web API和MVC应用程序混合到同一个项目/网站中。 需求和(DI)配置很可能需要不同,这将使得使用单个容器配置解决此问题的一切变得复杂。

因此,虽然完全有可能在同一个应用程序中运行MVC和Web API,并且可以使用单个容器,但我的建议是:不要这样做。 不仅从技术角度,而且从功能。 Web API是一种Web服务。 您也不会在同一个项目中将MVC与WCF混合使用。

但是如果你真的想要,你只需要注册System.Web.Mvc.DependencyResolver.SetResolver (对于MVC)和System.Web.Http.HttpConfiguration.DependencyResolver (对于Web API)。

如果要实现IDependencyResolver接口并将其与框架中的Application_Start: DependencyResolver.SetResolver()连接,WindsorDependencyScope将起作用

为了使它适用于Owin Startup,我重写了HttpConfigurationDependencyResolver

[assembly: OwinStartup(typeof(YourCompany.API.Startup))]
namespace YourCompany.API
{
    public partial class Startup
    {
        public void Configuration(IAppBuilder app)
        {
            HttpConfiguration config = new HttpConfiguration();
            var dependencyResolver = new WindsorHttpDependencyResolver(container);
            config.DependencyResolver = dependencyResolver;
            // ....... 
            // ....... 
        }
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM