4

Unity は ASP.NET Web API プロジェクトのすべてのコントローラーで適切に動作しています。NuGet ボックスから出てくるデフォルトのセットアップを使用するだけです。また、MVC フィルター属性に接続することもできましたが、ASP.NET Web API フィルター属性に対して同じことを行うことはできないようです。

このデフォルトの実装を拡張して、依存関係を ActionFilterAttribute に挿入する方法、たとえば...

public class BasicAuthenticationAttribute : ActionFilterAttribute
{
    [Dependency]
    public IMyService myService { get; set; }

    public BasicAuthenticationAttribute()
    {
    }
}

このフィルターは、属性を使用してコントローラーに適用されます。

[BasicAuthentication]

Unity コンテナーを接続して属性クラスの作成を処理する必要があることは確かですが、MVC フィルターと同じ拡張ポイントを使用しないため、どこから始めればよいかについての手がかりが必要です。

私が試した他のことには、依存関係の注入ではなくサービスの場所が含まれますが、返される DependencyResolver は、構成したものとは異なります。

// null
var service = actionContext.Request.GetDependencyScope().GetService(typeof(IMyService));

または

// null
var service = GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IApiUserService));
4

1 に答える 1

7

問題は、Attribute クラスが WebAPI フレームワークではなく .NET によって作成されることです。

さらに読む前に、IApiUserService で DependencyResolver を構成するのを忘れていませんか?

(IUnityContainer)container;
container.RegisterType<IApiUserService, MyApiUserServiceImpl>();
...
var service = GlobalConfiguration.Configuration.DependencyResolver.GetService(typeof(IApiUserService));

UnityContainer を保持する App_Start\UnityConfig クラスを作成しました。

public class UnityConfig {
    #region Unity Container
    private static Lazy<IUnityContainer> container = new Lazy<IUnityContainer>(() => {
        var container = new UnityContainer();
        RegisterTypes(container);
        return container;
    });

    /// <summary>
    /// Gets the configured Unity container.
    /// </summary>
    public static IUnityContainer GetConfiguredContainer() {
        return container.Value;
    }
    #endregion

    public static void Configure(HttpConfiguration config) {
        config.DependencyResolver = new UnityDependencyResolver(UnityConfig.GetConfiguredContainer());
    }

    /// <summary>Registers the type mappings with the Unity container.</summary>
    /// <param name="container">The unity container to configure.</param>
    /// <remarks>There is no need to register concrete types such as controllers or API controllers (unless you want to 
    /// change the defaults), as Unity allows resolving a concrete type even if it was not previously registered.</remarks>
    private static void RegisterTypes(IUnityContainer container) {
        // NOTE: To load from web.config uncomment the line below. Make sure to add a Microsoft.Practices.Unity.Configuration to the using statements.
        // container.LoadConfiguration();

        // TODO: Register your types here
        // container.RegisterType<IProductRepository, ProductRepository>();
        container.RegisterType<MyClass>(new PerRequestLifetimeManager(), new InjectionConstructor("connectionStringName"));
    }
}

UnityDependencyResolverとは、私が内部化したこのブログ投稿と Unity.WebApi (プロジェクト/ Nuget パッケージPerRequestLifetimeManager)から来ました。(ブートストラップなので)

他のコードで UnityContainer を使用する必要がある場合は、それをコンストラクターに渡しました。

config.Filters.Add(new MyFilterAttribute(UnityConfig.GetConfiguredContainer()));
于 2013-06-25T21:00:55.710 に答える