UPDATE : 간단한 인젝터 2.5 새로운 RegisterMvcIntegratedFilterProvider
확장 방법에
이전 RegisterMvcAttributeFilterProvider
대체 MVC 통합 패키지에 추가되고 있습니다. 이 새로운 RegisterMvcIntegratedFilterProvider
에는 아래에 주어진 SimpleInjectorFilterAttributeFilterProvider
의 동작이 포함되어 있으며 단순 주입기 파이프 라인에 특성을보다 잘 통합 할 수 있습니다. 그러나 기본적으로 속성이 주입되지는 않지만 custom IPropertySelectionBehavior을 구현하면 확장 할 수 있습니다. 새 RegisterMvcIntegratedFilterProvider
의 사용은 이전 RegisterMvcAttributeFilterProvider
메서드를 통해 진행되며 이후 릴리스에서는 [Obsolete]
으로 표시됩니다. MVC 속성에
RegisterMvcAttributeFilterProvider
확장 방법을 사용하여
는 간단한 인젝터는 등록 초기화를 호출하지 않습니다.
NotificationService
을 삽입하는 익명의 대리자 안에 중단 점을 설정하면 절대 적중하지 않는 것을 볼 수 있습니다. 그러나
InjectProperties
은 암시 적 속성 삽입을 수행합니다. 즉, 모든 공용 속성을 유형에 주입하려고 시도하지만 해당 속성을 삽입 할 수없는 경우 건너 뜁니다. (for 무슨 이유가 있었는지).
나는 대신 CriticalErrorAttribute.NotificationService
속성의 유형이 NotificationService
일 것입니다.NotificationService
을 명시 적으로 등록하지 않았기 때문에 컨테이너가 사용자 대신 임시 인스턴스를 생성하므로 나머지 응용 프로그램보다 많은 CriticalErrorAttribute
인스턴스가 생성됩니다.
빠른 수정 : 속성 유형을 INotificationService
으로 변경하십시오.
사실, 단순 주입기의 MVC 통합 패키지를 구현하여 InjectProperties
메소드를 사용하는 것은 유감 스럽습니다. Implicit Property injection은 잘못된 설정이있을 때 빠르게 실패하지 않고 나중에 InjectProperties
에 대한 지원을 제거 할 생각이기 때문에 매우 나쁜 것입니다. 문제는 많은 개발자가 InjectProperties
에 의존한다는 것입니다. 직접 호출하거나 컨테이너가 MVC 속성에 속성을 주입하도록함으로써 간접적으로 호출합니다.
InjectProperties
초기화 도구가 실행되지 않습니다. 그게 의도적인데 컨테이너에 의해 생성되지 않은 객체에 대해 전체 초기화 프로세스를 실행할 수있는 다른 구조가 있습니다. 그러나이 문제를 추가하면 기존 클라이언트가 손상 될 수 있습니다. 이로 인해 속성이 여러 번 주입 될 수 있습니다. 응용 프로그램의 시작 경로에 container.RegisterMvcAttributeFilterProvider()
를 호출
방지 : 귀하의 경우
, 나는 다른 해결책을 제안한다. 내부적으로 InjectProperties
을 호출하는 FilterAttributeFilterProvider
특수 문자가 등록됩니다. 암시 적 속성 주입을 사용하지 않으려는 경우보다 명확한 (그리고 완전한) 동작이 필요합니다.
internal sealed class SimpleInjectorFilterAttributeFilterProvider
: FilterAttributeFilterProvider
{
private readonly ConcurrentDictionary<Type, Registration> registrations =
new ConcurrentDictionary<Type, Registration>();
private readonly Func<Type, Registration> registrationFactory;
public SimpleInjectorFilterAttributeFilterProvider(Container container)
: base(false)
{
this.registrationFactory = type =>
Lifestyle.Transient.CreateRegistration(type, container);
}
public override IEnumerable<Filter> GetFilters(
ControllerContext context,
ActionDescriptor descriptor)
{
var filters = base.GetFilters(context, descriptor).ToArray();
foreach (var filter in filters)
{
object instance = filter.Instance;
var registration = registrations.GetOrAdd(
instance.GetType(), this.registrationFactory);
registration.InitializeInstance(instance);
}
return filters;
}
}
당신이 사용자 지정 공급자를 등록하려면 다음 코드를 사용할 수 있습니다 : 다음 Registration.InitializeInstance 메소드를 호출 SimpleInjectorFilterAttributeFilterProvider
var filterProvider =
new SimpleInjectorFilterAttributeFilterProvider(container);
container.RegisterSingle<IFilterProvider>(filterProvider);
var providers = FilterProviders.Providers
.OfType<FilterAttributeFilterProvider>().ToList();
providers.ForEach(provider => FilterProviders.Providers.Remove(provider));
FilterProviders.Providers.Add(filterProvider);
이 사용자 대신 다음 클래스를 등록합니다. 이 메서드는 이미 초기화 된 형식을 초기화 할 수 있으며 형식 이니셜 라이저 대리자를 호출하여 초기화합니다.
속성 작업에 대한 자세한 내용은 following discussion을 참조하십시오.
사용자 지정 IPropertySelectionBehavior를 구현하여 Simple Injector가 특성에 특성을 강제로 주입하도록 할 수도 있습니다. 이렇게하면 사용자 정의 초기화 프로그램을 작성할 필요가 없습니다. 가능한 경우 명시 적으로 속성을 등록하십시오. 이 방법은 그것들을 검증 할 수 있습니다. – Steven
'FilterProviders.Providers.Add (filterProvider);'가되어야합니까? – ajbeaven
@ajbeaven : 고마워요. 더 이상 쓸모없는 SimpleInjectorFilterAttributeFilterProvider에서 더 중요한 버그를 수정했습니다. – Steven