I am experiencing the following problem with Unity framework.
We have a singleton classes in our project. They have some properties that should be injected by Unity container. Here is the code:
private static SomeClass m_Instance;
private SomeClass()
{ }
public static SomeClass Instance
{
get
{
if (m_Instance == null)
{
lock (typeof(SomeClass))
{
if (m_Instance == null)
{
IUnityContainer container = ContainerAccessor.GetContainer();
m_Instance = container.BuildUp<SomeClass>(new SomeClass());
}
}
}
return m_Instance;
}
}
This code fails with the following exception: The type SomeClass cannot be constructed. You must configure the container to supply this value.
I've digged into Unity code and found out that the problem was caused by method PreBuildUp, which calls GuardTypeIsNonPrimitive, both defined in Microsoft.Practices.ObjectBuilder2.DynamicMethodConstructorStrategy class. Here is the piece of it's code:
public override void PreBuildUp(IBuilderContext context)
{
...
SelectedConstructor selectedConstructor = context.Policies.Get<IConstructorSelectorPolicy>(context.BuildKey, out list).SelectConstructor(context, list);
GuardTypeIsNonPrimitive(context, selectedConstructor);
...
}
private static void GuardTypeIsNonPrimitive(IBuilderContext context, SelectedConstructor selectedConstructor)
{
Type type = context.BuildKey.Type;
if (!type.IsInterface && ((type == typeof(string)) || (selectedConstructor == null)))
{
throw new InvalidOperationException(string.Format(CultureInfo.CurrentCulture, Resources.TypeIsNotConstructable, new object[] { type.Name }));
}
}
As we can see, Unity tries to find constructor for the class that should be built up. Since the only constructor defined for SomeClass is private, Unity finds nothing and passes null to GuardTypeIsNonPrimitive. And this method throws an exception. At the moment I have defined public constructor for SomeClass (just to prove the concept), everything worked out fine.
Questions:
UPDATE: Why does the BuildUp method requires constructor to be defined?
Any ideas how to work this around? (Remove singleton is not an option)