2010-11-26 45 views
2

上のコンポーネントの依存関係を設定し、それが何か使用して、既存のオブジェクトの依存関係を設定することが可能です:城ウィンザー:<a href="http://mef.codeplex.com/" rel="nofollow">MEF</a>では既存のオブジェクト

container.SatisfyImportsOnce(instance); 

Castle Windsorと同じことを行うために、それは可能ですか?

私は(読む:学習)Caliburn.Microを使用していて、MEFからWindsorにテンプレートプロジェクトを更新しようとしています。

+0

[解決の可能性の重複:完全にこの答えを完了するために、ここで依存性の注入(使用時)コントローラ(インスタンス化時)とのActionFilterの両方のための城ウィンザーのセットアップでのGlobal.asaxアプリケーションクラスの一例ですクラスを登録せずにCastle Windsorを使用してください(http://stackoverflow.com/questions/447193/resolving-classes-without-registering-them-using-castle-windsor) –

+0

これは 'container.BuildUp' Unityの機能を使用して、http://stackoverflow.com/questions/851940/windsor-castle-injecting-properties-of-constructed-objectを複製しますか? – mookid8000

+2

Jeez。どのように私は既存の質問を探しても、何も見つからないのですか?ああ、リンクのおかげで、重複して申し訳ありません。 –

答えて

2

申し訳ニール、ウィンザーはありません、その機能

Castle Windsor FAQ

ウィンザーは、プロパティの依存関係を(それは、オプションの依存関係を考慮している)のような解決しますそのサービスに登録されたコンポーネントがある場合、ILoggerプロパティ。しかし、これはコンポーネントのアクティベーション中にのみ発生します。コンポーネントが初めて構築された場合、Windsorに既存のインスタンスを渡してコンポーネントをプロパティに挿入する方法はありません。

+0

実際、私はウィンザーがこれを持っていないと考えています。 IPhoneのFlash非対応のようなものは、機能です。それは悪いです、しないでください。 –

+0

@ Krzysztofうん、私は完全に同意します。ウィンザーは、作成するコンポーネントの寿命を管理することを好んでいます。サンプルアプリケーションでStructureMapを使用してオブジェクトStructureMapの依存関係を解決する方法が必ずしも作成されていなかったというCaliburn.Microのメソッドがあるため、私は尋ねていました。私は城ウィンザーのファンですが、私は自分のアプリでCWを使いたいので、同等のものを探していました。 –

0

Castle Windsorを使用すると、既存のインスタンスをコンテナに登録できます。これは、探しているものですか?

var instance = new Logger(); 
var container = new WindsorContainer(); 

container.Register(Component.For<ILogger>().Instance(instance)) 

どこ

public interface ILogger 
{ 
    void LogException(Exception ex); 
} 

public class Logger : ILogger 
{ 
    public void LogException(Exception ex) 
    { 
    // Log exception 
    } 
} 
1

ただし、この機能を自分でコーディングすることはできます。たとえば、属性アクションフィルタにプロプライティを挿入するために使用されるASP.NET MVC FilterAttributeFilterProviderを次に示します。 BuildUpAttributeDependancies法で

public class AttributeFilterProvider : FilterAttributeFilterProvider 
    { 
    public AttributeFilterProvider(IKernel kernel) 
    { 
     _kernel = kernel; 
    } 

    private readonly IKernel _kernel; 

    protected override IEnumerable<FilterAttribute> GetControllerAttributes(ControllerContext controllerContext, ActionDescriptor actionDescriptor) 
    { 
     var attributes = base.GetControllerAttributes(controllerContext, actionDescriptor); 
     BuildUpAttributeDependancies(attributes); 
     return attributes; 
    } 

    protected override IEnumerable<FilterAttribute> GetActionAttributes(ControllerContext controllerContext, ActionDescriptor actionDescriptor) 
    { 
     var attributes = base.GetActionAttributes(controllerContext, actionDescriptor); 
     BuildUpAttributeDependancies(attributes); 
     return attributes; 
    } 

    private void BuildUpAttributeDependancies(IEnumerable<FilterAttribute> attributes) 
    { 
     foreach (var attribute in attributes) 
     { 
     var propInfos = attribute.GetType().GetProperties().Where(x => x.GetValue(attribute) == null).AsEnumerable(); 
     foreach (var pi in propInfos) 
     { 
      if (_kernel.HasComponent(pi.PropertyType)) 
      { 
      var service = _kernel.Resolve(pi.PropertyType); 
      pi.SetValue(attribute, service); 
      } 
     } 
     } 
    } 
    } 

、我々は非初期化(ヌル)のプロパティを探して、その後、型は城ウィンザーに登録されているかどうかを確認します。それがあった場合は、プロパティを設定します。

デフォルトのFilterAttributeFilterProviderをglobal.asaxファイルのカスタム(上記)に置き換えることで、Castle Windsors DIの機能を使用して、MVCアプリケーションの任意のアクションフィルタに任意のタイプを挿入できるようになりました。

public class MvcApplication : System.Web.HttpApplication 
{ 
    private static IWindsorContainer _container; 

    private static void BootstrapContainer() 
    { 
    _container = new WindsorContainer() 
     .Install(FromAssembly.This()); 

    var controllerFactory = new ControllerFactory(_container.Kernel); 
    ControllerBuilder.Current.SetControllerFactory(controllerFactory); 
    } 

    private static void BootstrapFilters() 
    { 
    var oldProvider = FilterProviders.Providers.Single(f => f is FilterAttributeFilterProvider); 
    FilterProviders.Providers.Remove(oldProvider); 

    var provider = new AttributeFilterProvider(_container.Kernel); 
    FilterProviders.Providers.Add(provider); 
    } 

    protected void Application_Start() 
    { 
    AreaRegistration.RegisterAllAreas(); 

    WebApiConfig.Register(GlobalConfiguration.Configuration); 
    FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); 
    RouteConfig.RegisterRoutes(RouteTable.Routes); 
    BundleConfig.RegisterBundles(BundleTable.Bundles); 

    BootstrapContainer(); 
    BootstrapFilters(); 
    } 
} 
+0

これが受け入れられる回答である必要があります。私は "いいえ、あなたはそれをすることはできませんが、ここには方法があります"のが好きです。:)私はどこかでこれをやっていたことを知っていました。あなたの答えを見て、それが私が注射していた属性であることを思い出しました。おそらく属性があまりにもインテリジェントな悪い練習は、コードも隠す。しかし、そうでない場合は、すでに構築されたオブジェクトに対してプロパティインジェクションを行う方法は知られていないでしょう。コンテナを徐々に導入するときに古いコードベースで作業するときに必要なものです。 –

関連する問題