5

この記事は、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 ロジックを同じアプリケーションに含める方法はありますか?

に設定DependencyResolver.SetResolver(...)した後application_start、アプリケーションの改善に気づきませんでした。

ご覧のように。

タイプ 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());
4

3 に答える 3

6

Microsoft は Web API を MVC アプリケーションと同じプロジェクトに入れることを推進しているようです (使用するテンプレートが原因です)。ただし、Web API と MVC アプリケーションを同じプロジェクト/Web サイトに混在させることはしません。要件と (DI) 構成が異なる必要がある可能性が非常に高く、単一のコンテナー構成を使用してこれを解決しようとすると、すべてが複雑になります。

したがって、MVC と Web API を同じアプリケーションで実行することは完全に可能であり、単一のコンテナーでも可能ですが、私のアドバイスは、これを行わないことです。技術的な観点だけでなく、機能的な観点からも。Web API は Web サービスです。また、同じプロジェクトで MVC と WCF を混在させないでください。

ただし、本当に必要な場合は、System.Web.Mvc.DependencyResolver.SetResolver(MVC 用) とSystem.Web.Http.HttpConfiguration.DependencyResolver(Web API 用) の両方を登録する必要があります。

于 2012-09-29T09:39:57.670 に答える
0

WindsorDependencyScope は、IDependencyResolver インターフェイスを実装し、それをフレームワーク int Application_Start: DependencyResolver.SetResolver()に接続する場合に機能します。

于 2012-09-29T04:55:59.590 に答える
0

Owin Startupで動作させるにDependencyResolverは、HttpConfiguration

[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;
            // ....... 
            // ....... 
        }
    }
}
于 2015-11-05T15:27:40.487 に答える