I have the following helper class which has public property _variableHandler. The property is public as I initially had visions of setting the property from the calling code before involving methods within the XAMLHelper class, but now doubt this is a smart approach. Mostly because I will need to call the class fairly often and not always update the value of _variableHandler, meaning things will get messy.
public class XAMLHelper
{
public IVariableTypeHandler _variableHandler;
public XAMLHelper()
{
}
}
I also have a factory which is used to provide the desired concrete instance of a VariableTypeHandler.
I am also using an IoC container (Unity) to provide a single instance of the XAMLHelper class, as shown below.
container.RegisterInstance<XAMLHelper>(new XAMLHelper());
Ideally, I would like to keep this single instance but simply update the value of _variableHandler when specified using like the code below.
container.Resolve(new PropertyInjection(VariableHandlerFactory.GetInstance("Str")));
I have tried adding snippets into container registration, such as a
new InjectionProperty()
But this doesn't seem to update the _variableHandler property once it has been instantiated the first time. Am I missing something important here? Or trying to do something that is not possible with an IoC container?
Generally, good design proposes making helper\manipulator\operation classes stateless. Here you clearly have a helper class which is stateful as you are able to set the state of the object through the property _variableHandler
(not real property, it is more like a field).
What you could do is to make factory for IVariableHandler
register that within the IoC and inject it into XAMLHelper
. Then when invoking helper you just specify which handler to use and re-create it with factory. Factory could be a bit smarter to reuse already create object using some kind of caching.
public intefrace IVariableHandlerFactory
{
IVariableHandler Get(string description);
}
public class VariableHandlerFactory : IVariableHandlerFactory
{
private readonly IDictionary<string, IVariableHandler> _cache;
public VariableHandlerFactory()
{
_cache = new Dictionary<string, IVariableHandler>();
}
public IVariableHandler Get(string description)
{
IVariableHandler handler;
if(_cache.TryGetValue(description, out handler))
{
return handler;
}
handler = //create it...
_cache[description] = handler;
return handler;
}
}
and then use that within XAMLHelper
public class XAMLHelper
{
private readonly IVariableHandlerFactory _factory;
public XAMLHelper(IVariableHandlerFactory factory)
{
_factory = factory;
}
public void HelpMe(string description)
{
var handler = _factory.Get(description);
//do actual work using handler
}
}
Let's put that aside, and discuss the real problem here. First, you are missing annotation of your property:
[Dependency]
public IVariableTypeHandler VariableHandler { get; set; }
then you could register the XAMLHelper
using the InjectionProperty
container.RegisterType<VariableTypeHandlerImpl, IVariableTypeHandler>();
using(var lifetime = new ContainerControlledLifetimeManager())
container.RegisterType<XAMLHelper>(lifetime, new InjectionProperty("VariableHandler");
or, if you have concrete instance of the IVariableTypeHandler
you could use:
var variableHandler = VariableHandlerFactory.GetInstance("Str");
using(var lifetime = new ContainerControlledLifetimeManager())
container.RegisterType<XAMLHelper>(lifetime, new InjectionProperty("VariableHandler", variableHandler);