What is the simplest way to extend Castle windsor to support private constructors for every service
We want to be able to Resolve services using Castle for implementation with private constructors.
This is a fictive "use case" for that:
public class SingletonClass : ISingletonClass
{
private SingletonClass() {...} // Class users cannot create an instance
public ISingletonClass Instance
{
get
{
// The intention here is to get an instance of this service
// it has previously been configured as singleton in the container
return Container.Resolve<ISingletonClass>();
}
}
}
We want to have the option to use those private constructors for every service, not only for a few specific cases. Hence, we're looking for a simple and generic solution for this.
We looked for a solution using a custom component activator but found that we have to overrides a not-so trivial part of the default component activator, e.g. CreateInstance method.
This is the code for this in the default component activator:
protected virtual object CreateInstance(CreationContext context, object[] arguments, Type[] signature)
{
object instance = null;
Exception exception;
Type implementation = base.Model.Implementation;
bool flag = base.Kernel.ProxyFactory.ShouldCreateProxy(base.Model);
bool flag2 = true;
if (!(flag || !base.Model.Implementation.IsAbstract))
{
throw new ComponentRegistrationException(string.Format("Type {0} is abstract.{2} As such, it is not possible to instansiate it as implementation of {1} service", base.Model.Implementation.FullName, base.Model.Service.FullName, Environment.NewLine));
}
if (flag)
{
flag2 = base.Kernel.ProxyFactory.RequiresTargetInstance(base.Kernel, base.Model);
}
if (flag2)
{
try
{
if (this.useFastCreateInstance)
{
instance = FastCreateInstance(implementation, arguments, signature);
}
else
{
instance = ActivatorCreateInstance(implementation, arguments);
}
}
catch (Exception exception1)
{
exception = exception1;
throw new ComponentActivatorException("ComponentActivator: could not instantiat开发者_JAVA技巧e " + base.Model.Implementation.FullName, exception);
}
}
if (flag)
{
try
{
instance = base.Kernel.ProxyFactory.Create(base.Kernel, instance, base.Model, context, arguments);
}
catch (Exception exception2)
{
exception = exception2;
throw new ComponentActivatorException("ComponentActivator: could not proxy " + base.Model.Implementation.FullName, exception);
}
}
return instance;
}
It would be much easier if we could only overrides "ActivatorCreateInstance" or "FastCreateInstance" but they're closed.
Are we on the wrong track?
Is there a much simpler way to do this in a generic manner?Thank you very much
PhilSince it's an open-source project, you can write your own component activator by copying and pasting the DefaultComponentActivator code, changing what you need and registering the activator. I've done it a few times with several other components of the Castle stack. When it's done, send in a patch.
精彩评论