Следуя совету принятого ответа, я смог расширить класс DefaultComponentActivator
для работы с конструкторами protected
(он по-прежнему не работает с private
или internal
; код ниже работает нормально, но что-то еще в цепочке создания DynamicProxy не работает).
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Castle.Core;
using Castle.MicroKernel;
using Castle.MicroKernel.ComponentActivator;
using Castle.MicroKernel.Context;
namespace /* YourNameSpaceHere */
{
[Serializable]
public class NonPublicComponentActivator : DefaultComponentActivator
{
public NonPublicComponentActivator(ComponentModel model, IKernelInternal kernel, ComponentInstanceDelegate onCreation, ComponentInstanceDelegate onDestruction)
: base(model, kernel, onCreation, onDestruction)
{ /* do nothing */ }
private readonly List<Type> loadedTypes = new List<Type>();
protected override ConstructorCandidate SelectEligibleConstructor(CreationContext context)
{
lock (loadedTypes)
{
if (!loadedTypes.Contains(context.RequestedType))
{
loadedTypes.Add(context.RequestedType);
// Add the missing non-public constructors too:
var ctors = context.RequestedType.GetConstructors
(
BindingFlags.NonPublic | BindingFlags.Instance
);
foreach (var ctor in ctors)
{
Model.AddConstructor
(
new ConstructorCandidate
(
ctor,
ctor.GetParameters().Select(pi => new ConstructorDependencyModel(pi)).ToArray()
)
);
}
}
}
return base.SelectEligibleConstructor(context);
}
}
}
Затем в вашем контейнере вы регистрируете это для объекта ComponentRegistration
с помощью общего метода Activator
, поэтому мой вызов container.Register выглядит примерно так:
_container.Register
(
// . . .
AllClasses.FromThisAssembly().BasedOn<ISomeInterface>()
.Configure
(
c => c.LifeStyle.Transient
.Interceptors<MyInterceptor>()
.Activator<NonPublicComponentActivator>() // <--- REGISTERED HERE
),
// . . .
);
Надеюсь, это кому-нибудь поможет!