温莎城堡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?

查看:191
本文介绍了温莎城堡ASP.NET MVC 4和Web API相同的应用程序。只有当MVC控制器有没有依赖性?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

<一个href=\"http://nikosbaxevanis.com/2012/07/16/using-the-web-api-dependency-resolver-with-castle-windsor-scoped-lifetime\"相对=nofollow>这篇文章是做网页API与温莎城堡一个很好的起点,但如果我创建一个简单的MVC控制器?它仅如果没有依赖关系到注射工作。

添加这一项,即:

 公共类HomeController的:控制器
{
    私人只读IValues​​Repository库;    公众的HomeController(IValues​​Repository库)
    {
        this.repository =库;
    }    公众的ActionResult指数()
    {
        返回查看();
    }
}

导致以下错误:


  此对象定义的

参数的构造函数


有没有办法让使用温莎城堡?

同一个应用程序的MVC和Web API逻辑

设置完成后 DependencyResolver.SetResolver(...)的Application_Start ,我没有注意到任何改善我的申请。

正如你所看到的。

实施服务定位:

 内部密封类WindsorDependencyResolver
    :ServiceLocatorImplBase,的IDependencyResolver
{
    私人只读IWindsorContainer容器;    公共WindsorDependencyResolver(
        IWindsorContainer容器)
    {
        如果(集装箱== NULL)
        {
            抛出新的ArgumentNullException(容器);
        }        this.container =容器;
    }    公共对象GetService的(T型)
    {
        返回this.container.Kernel.HasComponent(T)
             ? this.container.Resolve(T):空;
    }    公共IEnumerable的&LT;对象&gt; GetServices(T型)
    {
        返回this.container.ResolveAll(T)
            .Cast&所述;对象&gt;()ToArray的();
    }    公共IDependencyScope BeginScope()
    {
        返回新WindsorDependencyScope(this.container);
    }    公共无效的Dispose()
    {
    }    保护覆盖对象DoGetInstance(
        类型的serviceType,串键)
    {
        如果(关键!= NULL)
            返回container.Resolve(键,的serviceType);
        返回container.Resolve(的serviceType);
    }    保护覆盖的IEnumerable&LT;对象&gt; DoGetAllInstances(
        类型的serviceType)
    {
        回报(对象[])container.ResolveAll(的serviceType);
    }

把我带回到了起点。

终于解决了。

下面是为别人解决方案


在的Application_Start ...

  // MVC
DependencyResolver.SetResolver(
    新WindsorMvcDependencyResolver(容器));//网页API:
VAR httpDependencyResolver =
    新WindsorHttpDependencyResolver(容器);GlobalConfiguration.Configuration.DependencyResolver =
    httpDependencyResolver;内部类WindsorMvcDependencyResolver
    :WindsorDependencyScope,的IDependencyResolver
{
    私人只读IWindsorContainer容器;    公共WindsorMvcDependencyResolver(
        IWindsorContainer容器):基地(容器)
    {
        this.container =容器;
    }
}
内部密封类WindsorHttpDependencyResolver
    :的IDependencyResolver
{
    私人只读IWindsorContainer容器;    公共WindsorHttpDependencyResolver(
        IWindsorContainer容器)
    {
        如果(集装箱== NULL)
        {
            抛出新的ArgumentNullException(容器);
        }        this.container =容器;
    }    公共对象GetService的(T型)
    {
        返回this.container.Kernel.HasComponent(T)
             ? this.container.Resolve(T):空;
    }    公共IEnumerable的&LT;对象&gt; GetServices(T型)
    {
        返回this.container.ResolveAll(T)
            .Cast&所述;对象&gt;()ToArray的();
    }    公共IDependencyScope BeginScope()
    {
        返回新WindsorDependencyScope(this.container);
    }    公共无效的Dispose()
    {
    }
}内部类WindsorDependencyScope:IDependencyScope
{
    私人只读IWindsorContainer容器;
    私人只读IDisposable的范围;    公共WindsorDependencyScope(
        IWindsorContainer容器)
    {
        如果(集装箱== NULL)
        {
            抛出新的ArgumentNullException(容器);
        }        this.container =容器;
        this.scope = container.BeginScope();
    }    公共对象GetService的(T型)
    {
        返回this.container.Kernel.HasComponent(T)
            ? this.container.Resolve(T):空;
    }    公共IEnumerable的&LT;对象&gt; GetServices(T型)
    {
        返回this.container.ResolveAll(T)
            .Cast&所述;对象&gt;()ToArray的();
    }    公共无效的Dispose()
    {
        this.scope.Dispose();
    }
}

和登记为MVC和Web API控制器

  container.Register(类
    .FromAssemblyContaining&LT;&HomeController的GT;()
    .BasedOn&LT;控制器与GT;()
    .LifestylePerWebRequest());
container.Register(类
    .FromAssemblyContaining&LT; Values​​Controller&GT;()
    .BasedOn&LT; IHttpController&GT;()
    .LifestyleScoped());


解决方案

微软似乎把推进网络API到同一项目作为一个MVC应用程序(由他们使用的模板)。不过,我不会混在Web API和MVC应用程序到同一个项目/网站。这是非常可能的是,要求和(DI)配置需要是不同的,这将使一切复杂试图解决此使用一个单个容器的配置。

所以,虽然它是完全可能有MVC和Web API在同一应用程序中运行,它是可能的一个容器中,我的建议是:不这样做。不仅从技术的角度来看,也从功能。一个Web API是一个Web服务。你也不会在同一个项目中使用WCF混合MVC。

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

This article is a good starting point for doing Web API with Castle Windsor, but what if I create a simple MVC controller? It only works if there is no dependency into the inject.

Adding this one, i.e.:

public class HomeController : Controller
{
    private readonly IValuesRepository repository;

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

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

Causes the following error :

parameterless constructor defined for this object

Is there a way to have MVC and Web API logic in a same application using Castle Windsor?

After setting DependencyResolver.SetResolver(...) in application_start, I didn't notice any improvement in my application.

As you can see.

Implementing the service locator :

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);
    }

took me back to the starting point.

Finally solved.

Here's the solution for someone else


In 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();
    }
}

And the registration for both mvc and web api controller

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


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

解决方案

Microsoft seems to promote putting Web API into the same project as an MVC application (caused by the template they use). However, I wouldn't mix a Web API and an MVC application into the same project/website. It is very likely that the requirements and (DI) configurations need to be different, which will make everything complex trying to solve this using one single container configuration.

So although it is completely possible to have MVC and Web API running in the same application, and it is possible with a single container, my advice is: don't do this. Not only from a technical perspective, but also from a functional. A Web API is a Web Service. You also wouldn't mix MVC with WCF in the same project.

But if you really want to, you'll just have to register both the System.Web.Mvc.DependencyResolver.SetResolver (for MVC) and System.Web.Http.HttpConfiguration.DependencyResolver (for Web API).

这篇关于温莎城堡ASP.NET MVC 4和Web API相同的应用程序。只有当MVC控制器有没有依赖性?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆