나는이 동일한 문제가 있었고, 나는 해결책을 취했다. 다음 클래스를 고려
public class InjectionInterceptor : IInterceptor {
private readonly ILifetimeScope _Scope;
public InjectionInterceptor(ILifetimeScope scope) {
_Scope = scope;
}
public void Intercept(IInvocation invocation) {
using (var lifetime = _Scope.BeginLifetimeScope(string.Format("InjectionInterceptor {0}", Guid.NewGuid()))) {
InjectDependencyIfNecessary(invocation, lifetime);
invocation.Proceed();
}
}
private void InjectDependencyIfNecessary(IInvocation invocation, ILifetimeScope lifetime) {
int indexOfDependencyArgument = FindDependencyArgument(invocation.Method);
if (indexOfDependencyArgument >= 0 && invocation.GetArgumentValue(indexOfDependencyArgument) == null) {
SetDependencyArgument(invocation, indexOfDependencyArgument, lifetime);
}
}
private static int FindDependencyArgument(System.Reflection.MethodInfo method) {
var allArgs = method.GetParameters();
return Array.FindIndex(allArgs, param =>
param.ParameterType.IsInterface &&
param.ParameterType.IsGenericType &&
param.ParameterType.GetGenericTypeDefinition() == typeof(IGeneric<>));
}
private void SetDependencyArgument(IInvocation invocation, int indexOfDependencyArgument, ILifetimeScope lifetime) {
var methodArg = invocation.Method.GetGenericArguments().Single();
var dependency = lifetime.Resolve(typeof(IGeneric<>).MakeGenericType(methodArg));
invocation.SetArgumentValue(indexOfDependencyArgument, dependency);
}
}
클라이언트 클래스는이 클래스에 의해 차단되는 등록
var builder = new ContainerBuilder();
builder.RegisterType<InjectionInterceptor>();
builder.RegisterType<ClientClass>()
.EnableClassInterceptors()
.InterceptedBy(typeof(InjectionInterceptor));
이 IGeneric의 인스턴스를 허용하도록 방법을 변경
: 가정
public class ClientClass
{
public virtual void DoSomething<T>(IGeneric<T> dependency = null) //must be virtual to be intercepted
{
if (dependency == null) throw new ArgumentNullException(nameof(dependency));
//use dependency here
}
}
당신의 ClientClass가 Autofac에 의해 해결되면, (가상으로 표시된) 모든 메소드가이 클래스에 의해 인터셉트됩니다. 메소드 인수를 검사하고 IGeneric 인 메소드를 찾으려고 시도합니다. 전달 된 인수가 null이면 호출 된 메서드의 제네릭 형식 매개 변수를 검사하고 IGeneric의 인스턴스를 확인합니다. 그런 다음 인수를 해당 확인 된 값으로 설정합니다.
당신은 종속 기본 매개 변수 필요가 없습니다,하지만 당신은 일반적으로이하는 것처럼 원하는 경우 여전히 당신에게 특정 유형을 주입 할 수있는 옵션을 제공하는 동안, 당신은 당신의 메소드를 호출 할 수 있습니다 :
client.DoSomething<int>(); //injected by the interceptor
client.DoSomething(new Generic<int>()); // resolved manually; interceptor does nothing
이 메소드에 대한 한 가지 큰 단점은 빈 인자 목록을 사용하여 DoSomething() 메소드를 호출하는 경우 코드에서 작업하거나 디버깅하는 다른 사람들에게 이해하기가 어렵다는 것입니다.
@downvoter, 의견이 있으십니까? –
인터페이스 인스턴스를 만들 수 없습니다. 이 인터페이스를 구현하는 클래스가 필요합니다. 따라서 인터페이스가 발견되면 해당 클래스를 * 사용하도록 컨테이너를 구성해야합니다. 그렇지 않습니까? 아마도 이것은 ypu 도움이 될 수 있습니다 : http://stackoverflow.com/questions/1189519/resolving-generic-interface-with-autofac – HimBromBeere
ypur 질문 많은 노력을 보여주지 않기 때문에 downvote 아마도 등장했다. 당신의 질문은 * 인스턴스를 얻거나 * 클래스를 인터페이스에 등록 *하고 있습니까? – HimBromBeere