2

これは可能だと聞きましたが、これがどのように機能するか想像できません。

プロジェクトに依存性注入 (autofac) を使用しています。私は他の誰かとプロジェクトを開発し、彼のクラスのメソッドを呼び出します (私は彼のアセンブリを使用します)。

次に、他の人が自分の操作に使用するオブジェクトのインスタンスを取得します。すべてのメソッドでこのオブジェクト インスタンスを渡すことを避け、autofac を使用します。

パラメーターを渡さずに、アセンブリ プロジェクトでこのインスタンスを解決できますか? 少なくとも DI-Container を渡す必要があると思います...しかし、依存性注入の概念により、「実行コンテキスト」全体でオブジェクトを解決し、同じものを取得できるようになるはずだと聞きました。

asp.net Web API の例を次に示します。

これは、asp.net webapi プロジェクトの API コントローラーです。

public class DocumentsController : ApiController
{
    // GET /api/documents
    public HttpResponseMessage Get()
    {
        // Here I call the method of the other developer, 
        // security/authorization should be handled in 
        // his method!
        // In this context the WebAPI provides the 
        // IPrincipal of the current user in this 
        // variable => "HttpContext.Current.User" but we 
        // don't want to pass it on every method call
        ClassFromOtherAssembly.GetDocuments();

        HttpResponseMessage response = 
            Request.CreateResponse<IEnumerable<Document>>(
                HttpStatusCode.OK, documents);

        return response;
    }
}

これは他の開発者のクラスです。彼はドキュメントを配信し、ユーザーが承認されているかどうかを確認する必要があります。

public class ClassFromOtherAssembly
{
    public List<Documents> GetDocuments()
    {
        //Security check
        IPrincipal principal = 
            DI_Container.Resolve(IPrincipal);

        if(principal.IsInRole("Admin"))
        {
            //return the list
        }
        else
        {
            //return empty list
        }
    }
}
4

2 に答える 2

3

いいえ、コンテナ自体を渡さないでください。Service Locatorのパターンに行き着きます。クイック検索を行うと、このパターンには腐った臭いがあることがわかります。

public class Foo
{
    private IContainer container;
    private IBar bar;

    public Foo( IContainer container) //no-no
    {
         this.container = container;
         this.bar = container.Resolve<IBar>();
    }
}

代わりに、適切な DI を使用します。

public class Foo
{
    private IBar bar;

    public Foo(IBar bar)
    {
        this.bar = bar;
    }
}

型がどのアセンブリにあるかは問題ではありません。これが IoC と DI の要点です。つまり、アプリケーションの一部を切り離し、具体的な実装ではなく抽象化に依存させることです。


編集
Service locator パターンと DI を誤解しました。「パラメーターを渡す代わりに、依存性注入を使用したい」 - パラメーターを渡すことは DI であり、対照的に、静的コンテナーから型を解決することはサービス ロケーターです。

public class DocumentsController : ApiController
{
    public HttpResponseMessage Get()
    {
        ClassFromOtherAssembly.GetDocuments(); //this is Service locator
        //really bad for testability and maintenance
        ...
    }
}

DIはこんな感じ

public class DocumentsController : ApiController
{
    private IDocumentProvider;

    public DocumentsController(IDocumentProvider provider)
    {
        this.provider = provider;
    }

    public HttpResponseMessage Get()
    {
        provider.GetDocuments(); //this is DI
        ...
    }
}
于 2012-07-06T09:44:26.400 に答える
1

Resolve を直接呼び出して ServiceLocator (アンチパターン) を使用しているGetDocuments()

IPrinciple を渡すには、コンストラクター インジェクションで制御の反転を使用します。

public class ClassFromOtherAssembly
{
    private IPrincipal principal;

    public ClassFromOtherAssembly(IPrincipal principal)
    {
        this.principal = principal;
    }

    public List<Documents> GetDocuments()
    {
        //Security check
        if (principal.IsInRole("Admin"))
        {
            //return the list
        }
        else
        {
            //return empty list
        }
    }
}
于 2012-07-06T09:43:59.740 に答える