the_drow the_drow - 1 month ago 7
C# Question

How to write a custom windsor activator that creates objects by a string?

I have a console application that recieves a class name and calls a function of it:

Assembly asm = Assembly.GetEntryAssembly();
ObjectHandle oh = Activator.CreateInstance(asm.FullName, typeName);

IScheduledTask task = (IScheduledTask)oh.Unwrap();
task.Execute();


Until now, there was no need for initialization to occur besides that but now we have some components that IScheduledTask will depand on, through constructor injection.

Is there a way to define a named instance with the same name of the class, that will later on resolve all dependencies using resolve?

That is if I get "SomeScheduledTask" as a parameter I can do this:

IScheduledTask task = (IScheduledTask)container.Resolve(typeName); // I know this is possible. The problem is the registration.


Can I do something like this to resolve my issue:

container.Register(Component.For<IScheduledTask>().Named(t => t.Name).Activator<MyActivator>())


And in my activator do something like this:

public class MyActivator : IComponentActivator
{
public object Create(CreationContext context)
{
string typeName = context.???; // How do I get the named instance name from here?
Assembly asm = Assembly.GetEntryAssembly();
ObjectHandle oh = Activator.CreateInstance(asm.FullName, typeName);

IScheduledTask task = (IScheduledTask)oh.Unwrap();
task.Execute();
}

public void Destroy(object instance)
{

}
}

Answer

If I understand correctly, the problem is that you don't know beforehand what implementation type for IScheduledTask will be used, so you can't register it normally. If that's the case, IComponentActivator is not the right extension point to use. Try ILazyComponentLoader instead.

If you do know what possible IScheduledTask implementations the program might use, scan and register them normally.

Comments