その間に解決策を見つけました。これは簡単な修正ですが、InterceptionとTypeInterceptionStrategyをオーバーライドする必要があります。修正は、ポリシーリストから出てくるタイプを確認するだけのワンライナーでした。
これはTypeInterceptionStrategyからのコードです:
if (originalConstructorSelectorPolicy is DefaultUnityConstructorSelectorPolicy)
{
containingPolicyList.Set<IConstructorSelectorPolicy>(new CustomDerivedTypeConstructorSelectorPolicy(proxyType, originalConstructorSelectorPolicy), context.BuildKey);
}
もちろん、これを変更するには、TypeInterceptionStrategyをコピーして、その修正だけで同じことを行う必要があります。PreBuildUpメソッドをオーバーライドするだけで修正することはできません。
他の人が問題に遭遇した場合に備えて、修正全体をここに貼り付けています。
public class CustomTypeInterceptionStrategy : BuilderStrategy
{
public override void PreBuildUp(IBuilderContext context)
{
Guard.ArgumentNotNull(context, "context");
if (context.Existing != null)
{
return;
}
Type type = context.BuildKey.Type;
ITypeInterceptionPolicy typePolicy = FindInterceptionPolicy<ITypeInterceptionPolicy>(context);
if (typePolicy == null)
{
return;
}
ITypeInterceptor interceptor = typePolicy.GetInterceptor(context);
if (!interceptor.CanIntercept(type))
{
return;
}
IInterceptionBehaviorsPolicy behaviorPolicy = FindInterceptionPolicy<IInterceptionBehaviorsPolicy>(context);
IEnumerable<IInterceptionBehavior> interceptionBehaviors = behaviorPolicy == null
? Enumerable.Empty<IInterceptionBehavior>()
: behaviorPolicy.GetEffectiveBehaviors(context, interceptor, type, type).Where(ib => ib.WillExecute);
IAdditionalInterfacesPolicy interceptionPolicy3 = FindInterceptionPolicy<IAdditionalInterfacesPolicy>(context);
IEnumerable<Type> additionalInterfaces1 = interceptionPolicy3 != null ? interceptionPolicy3.AdditionalInterfaces : Type.EmptyTypes;
context.Policies.Set(new CustomEffectiveInterceptionBehaviorsPolicy() { Behaviors = interceptionBehaviors }, context.BuildKey);
Type[] additionalInterfaces2 = Intercept.GetAllAdditionalInterfaces(interceptionBehaviors, additionalInterfaces1);
Type proxyType = interceptor.CreateProxyType(type, additionalInterfaces2);
IPolicyList containingPolicyList;
IConstructorSelectorPolicy originalConstructorSelectorPolicy = context.Policies.Get<IConstructorSelectorPolicy>(context.BuildKey, out containingPolicyList);
if (originalConstructorSelectorPolicy is DefaultUnityConstructorSelectorPolicy)
{
containingPolicyList.Set<IConstructorSelectorPolicy>(new CustomDerivedTypeConstructorSelectorPolicy(proxyType, originalConstructorSelectorPolicy), context.BuildKey);
}
}
public override void PostBuildUp(IBuilderContext context)
{
Guard.ArgumentNotNull(context, "context");
IInterceptingProxy interceptingProxy = context.Existing as IInterceptingProxy;
if (interceptingProxy == null)
{
return;
}
CustomEffectiveInterceptionBehaviorsPolicy interceptionBehaviorsPolicy = context.Policies.Get<CustomEffectiveInterceptionBehaviorsPolicy>(context.BuildKey, true);
if (interceptionBehaviorsPolicy == null)
{
return;
}
foreach (IInterceptionBehavior interceptor in interceptionBehaviorsPolicy.Behaviors)
{
interceptingProxy.AddInterceptionBehavior(interceptor);
}
}
private static TPolicy FindInterceptionPolicy<TPolicy>(IBuilderContext context) where TPolicy : class, IBuilderPolicy
{
TPolicy policy = context.Policies.Get<TPolicy>(context.BuildKey, false);
if (policy != null)
{
return policy;
}
return context.Policies.Get<TPolicy>(context.BuildKey.Type, false);
}
private class CustomEffectiveInterceptionBehaviorsPolicy : IBuilderPolicy
{
public CustomEffectiveInterceptionBehaviorsPolicy()
{
this.Behaviors = new List<IInterceptionBehavior>();
}
public IEnumerable<IInterceptionBehavior> Behaviors { get; set; }
}
private class CustomDerivedTypeConstructorSelectorPolicy : IConstructorSelectorPolicy
{
private readonly Type interceptingType;
private readonly IConstructorSelectorPolicy originalConstructorSelectorPolicy;
public CustomDerivedTypeConstructorSelectorPolicy(Type interceptingType, IConstructorSelectorPolicy originalConstructorSelectorPolicy)
{
this.interceptingType = interceptingType;
this.originalConstructorSelectorPolicy = originalConstructorSelectorPolicy;
}
public SelectedConstructor SelectConstructor(IBuilderContext context, IPolicyList resolverPolicyDestination)
{
return FindNewConstructor(this.originalConstructorSelectorPolicy.SelectConstructor(context, resolverPolicyDestination), this.interceptingType);
}
private static SelectedConstructor FindNewConstructor(SelectedConstructor originalConstructor, Type interceptingType)
{
ParameterInfo[] parameters = originalConstructor.Constructor.GetParameters();
SelectedConstructor selectedConstructor = new SelectedConstructor(interceptingType.GetConstructor(parameters.Select(pi => pi.ParameterType).ToArray()));
foreach (string newKey in originalConstructor.GetParameterKeys())
{
selectedConstructor.AddParameterKey(newKey);
}
return selectedConstructor;
}
}
}
public class CustomInterception : Interception
{
protected override void Initialize()
{
this.Context.Strategies.AddNew<InstanceInterceptionStrategy>(UnityBuildStage.Setup);
this.Context.Strategies.AddNew<CustomTypeInterceptionStrategy>(UnityBuildStage.PreCreation);
this.Context.Container.RegisterInstance(typeof(AttributeDrivenPolicy).AssemblyQualifiedName, (InjectionPolicy)new AttributeDrivenPolicy());
}
}