I'm new to Unity and have a problem with configuration and nested generic types in a WCF service. Everything has been working fine until I hit the situation where I needed to define a factory which returns instances of types based on a generic interface.
The code looks something like this:
public interface IFactory<T, TResult>
{
TResult CreateInstance(T input);
}
public interface IFilter<T>
{
// throws an exception if an item is to be filtered
void Filter(T itemToFilter);
}
// classes implementing this interface can have multiple filters
public interface IFilterRunner<T>
{
void RunFilters(T itemToFilter);
}
public class FilterRunnerFactory : IFactory<BaseType, IFilterRunner<BaseType>>
{
public IFilterRunner<BaseType> CreateInstance(BaseType input)
{
if (input is SubType)
{
return new SubTypeFilterRunner();
}
throw new InvalidOperationException("Could not create an IFilterRunner for the input.");
}
}
public class Service
{
private readonly IFactory<BaseType, IFilterRunner<BaseType>> _filterRunnerFactory;
public Service(IFactory<BaseType, IFilterRunner<BaseType>> filterRunnerFactory)
{
_filterRunnerFactory = filterRunnerFactory;
}
}
The Unity configuration looks something like this:
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<alias alias="BaseType" type="SomeNamespace.BaseType, SomeAssembly, Version=1.0.0.0, Culture=neutral" />
<alias alias="IFactory" type="SomeNamespace.IFactory`2, SomeAssembly, Version=1.0.0.0, Culture=neutral" />
<alias alias="IFilterRunner" type="SomeNamespace.IFilterRunner`1, SomeAssembly, Version=1.0.0.0, Culture=neutral" />
<alias alias="IService" type="SomeNamespace.IService, SomeAssembly, Version=1.0.0.0, Culture=neutral" />
<containers>
<container>
<register type="IFactory[BaseType,IFilterRunner]" mapTo="SomeNamespace.FilterRunnerFactory, SomeAssembly, Version=1.0.0.0, Culture=neutral"/>
<register type="IService" mapTo="SomeNamespace.Service, SomeAssembly, Version=1.0.0.0, Culture=neutral">
<constructor>
<param name="filterRunnerFactory" />
</constructor>
</register>
</container>
</containers>
</unity>
The configuration seems valid but when the WCF service itself is instantiated I get the following error:
InvalidOperationException - The current type, SomeNamespace.IFactory
2[SomeNamespace.BaseType,SomeNamespace.IFilterRunner
1[SomeNamespace.BaseType]], is an interface and cannot be constructed. Are you missing a type mapping?
I’ve tried all sorts of different options but they all result in invalid configuration. Also, I have had other factory definitions that are defined to return either abstract base types or instances of types based on non-generic interfaces and they have worked fine. The difference is that this factory returns IFilterRunner - a generic interface.
Does anyone have any suggestions? Thanks in advance from a perplexed developer.