2017-01-17 1 views
2

私は次のセットアップにninject追加しようとしている - BaseControllerにILoggerですパラメータを追加すると、素晴らしい作品、ninjectで子コントローラを変更せずにコントローラのパラメータを受け入れる基本クラスを作成するにはどうすればよいですか?

public class BaseController : Controller 
{ 
    protected ILogger Logger {get;} 
    public BaseController() { Logger = new MyLogger(); } 
} 
public class Controller1Controller : BaseController { ... } 
public class Controller2Controller : BaseController { ... } 
.... 
public class ControllerNController : BaseController { ... } 

-

public class BaseController : Controller 
{ 
    protected ILogger Logger {get;} 
    public BaseController(ILogger logger) { Logger = logger; } 
} 

を今、それはまた、それぞれにコンストラクタを追加する必要があります親クラスにはパラメータのないコンストラクタが存在しないため、子クラスの子クラスは存在しません。

public class Controller1Controller : BaseController { 
    public Controller1Controller(ILogger logger) : base(logger) { } 
} 

より多くの依存関係を追加/削除する必要がある場合は、保守上の問題となる可能性があります。さらに、各コントローラに追加されるコードはまったく同じです。

子コントローラを(コンストラクタなしで)そのままにしても、それでもBaseControllerを変更する方法はありますか?

+0

は[ReSharperの](https://www.jetbrains.com/resharper/)などのリファクタリングツールを使用します。 –

+0

[Ninjectの使用に関する質問](http://stackoverflow.com/questions/36221865/questions-about-using-ninject) – NightOwl888

答えて

1

申し訳ありませんが、これを試してみてください記事/ Mark Seemannからブログや彼の本を読んで行ってください。

代替ソリューションとして、あなたはNinjectからILoggerですを取得することができます:Using property injection instead of constructor injection

+0

ありがとうございます。これは問題を解決しましたが、プロパティが公開され、セッターを持っていなければならないという警告がありましたので、これまでのテストで見たことから、非公開または読み取り専用のプロパティでは機能しません。 – Achilles

+0

あなたはNinjectカーネルへのアクセス権を持っているなら、あなたはこのようにそれを得ることができます。 'パブリッククラスBaseController:ILoggerですロガー{取得保護コントローラ { ;} 公共BaseController(){ \tロガーを= Kernel.Get () ; } } – tomludd

+0

@tomludd:これはDIではなく、これはサービスロケーションです。そしてそれは一種の反パターンです。 http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern – Nauman

1

単純な答え:いいえ(あなたの派生クラスのコンストラクタを更新する必要がある)

説明:派生とベースクラスを通過するILoggerですが注入さたとえば、あなたがILoggerですパラメータを使用して派生コンストラクタを更新する必要があり、その後、パラメータをベースに転送します。そうでないと、この状況にはもっと賢明な解決策があります。

DI Disadvantages(DIは、この荷物が付属しています)

またwikiに不利益セクションの最初のポイントを参照してください:あなたは、この保護されたインスタンスを作るであろう、ILoggerですインスタンスを保持するために、基本クラスで保護されたメンバーを作成することができますすべての派生クラスにアクセスできます。

更新:プロパティ注入を使用したtomluddのソリューションに部分的に同意します。 this SO answerを参照してください。 よりDIの技術については、DI in .NET

+0

ありがとうございます。なぜtomluddのソリューションに部分的に同意するのですか? – Achilles

+0

@Achilles:セッター/プロパティインジェクションを使うと、注入可能なプロパティを "public"にする必要があります。この場合、DIフレームワークはこれらのルールを指示しています。さらに、SOの質問への私の答えのリンクを参照してください。 また、ベースコントローラーのカーネルにアクセスするソリューションは、アンチパターンのようなもので、DIを採用する目的を破っています。あなたはサービスの場所を行っていますこのブログの記事を参照してください:http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/ – Nauman

+0

ありがとう、今は理にかなっています。有益なリンクをありがとう。 – Achilles

0

はありませんが、BaseControllerコンストラクタ

public BaseController(ILogger logger = null) 
{ 
    if (logger != null) 
     Logger = logger; 
    else 
     Logger = new MyLogger(); 
} 
+0

これで根本的な問題は解決しません。 – Achilles

関連する問題