A Castle Windsor question: Is it possible to register a class that has an internal constructor with the container?
Thanks Joni
Following the accepted answer's advice, I was able to extend the DefaultComponentActivator class to work with protected constructors (it still does not work with private or internal; the code below works fine, that is, but something else in the DynamicProxy creation chain fails).
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 loadedTypes = new List();
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);
}
}
}
Then, on your container you register this against a ComponentRegistration object via the generic Activator method, so my container.Register call looks something like this:
_container.Register
(
// . . .
AllClasses.FromThisAssembly().BasedOn()
.Configure
(
c => c.LifeStyle.Transient
.Interceptors()
.Activator() // <--- REGISTERED HERE
),
// . . .
);
Hope that helps someone!