2010-11-26 4 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에 응용 프로그램 클래스의 예입니다, 완전히이 답변을 완료하려면 클래스 캐슬 윈저를 사용하여 그들을 등록하지 않고 (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. 어떻게 기존의 질문을 찾고, 찾지 못했습니까? 결국 6 명이 내게 자신을 키울 때 중복 된 것을 보여 줍니까? 오, 링크에 감사드립니다. 복제본에 대해 유감스럽게 생각합니다. –

답변

2

죄송 닐, 윈저하지 않는 기능

Castle Windsor FAQ

윈저는 속성 의존성을 (이 옵션 의존성을 고려하는)과 같은 해결됩니다 해당 서비스에 대해 등록 된 구성 요소가있는 경우 ILogger 속성 그러나 이것은 구성 요소 활성화 중에 만 발생합니다 ... 구성 요소가 처음 구성되었을 때 Windsor를 기존 인스턴스에 전달하고 구성 요소를 속성에 삽입 할 수있는 방법이 없습니다.

+0

사실, 윈저는이 기능이 없다고 생각합니다. 아이폰이 플래시를 지원하지 않는 것은 일종의 기능이다. 그것은 나쁘다.하지 마라. –

+0

@ Krzysztof 네, 전적으로 동의합니다. Windsor가 만든 구성 요소의 수명을 관리하는 것을 선호합니다. Caliburn.Micro에 메서드가 있기 때문에 묻는 것입니다. 샘플 앱에서 StructureMap을 사용하여 ObjectMap의 종속성을 해결할 필요는 없습니다. 나는 성 (Castle) 윈저 팬이지만, 그래서 내 자신의 앱에서 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); 
      } 
     } 
     } 
    } 
    } 

, 우리는 초기화되지 않은 (NULL) 특성을 찾아 다음 유형 성 윈저에 등록되어 있는지 확인한다. 있다면 우리는 속성을 설정합니다.

기본 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

이것은 허용 된 대답이어야합니다. 나는 "네가 할 수는 없지만, 어떻게 할 수 있느냐"는 것을 좋아한다.:) 나는 어딘가 전에 이것을 한 것을 알았고 당신의 대답을 보았을 때 그것이 내가 주입하고 있던 속성이라는 것을 기억했다. 아마 너무 지능적인 속성을 가지고있는 나쁜 습관은 코드를 숨 깁니다. 그러나 그 것이 아니라면, 이미 구축 된 객체에 속성 주입을하는 방법을 알지 못했을 것입니다. 컨테이너를 점차적으로 도입 할 때 오래된 코드 기반으로 작업 할 때 필요합니다. –