If I have a class that implements a generic interface it works fine to configure it using the unity xml config.
public interface IReader<T> { }
public class Fund { }
public class FundReader : IReader<Fund> { }
and the unity xml:
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<namespace name="System.ComponentModel" />
<namespace name="TestUnityIssue" />
<assembly name="TestUnityIssue" />
<container>
<register type="IReader[Fund]" mapTo="FundReader" />
</container>
</unity>
And this works just using the following code:
var container = new UnityContainer().LoadConfiguration();
var fundReader = container.Resolve<IReader<Fund>>();
However, in some cases there is a wrapper around the type used in the reader. For example, adding the following two classes:
public class Wrapper<T> { }
public class WrappedFundReader : IReader<Wrapper<Fund>> { }
and if I add the following to the unity config:
<register type="IReader[Wrapper[Fund]]" mapTo="WrappedFundReader" />
and then try to resolve it using:
var wrappedReader = container.Resolve<IReader<Wrapper<Fund>>>();
I get the following exception:
InvalidOperationException - The current type,
TestUnityIssue.IReader`1[TestUnityIssue.Wrapper`1[TestUnityIssue.Fund]],
is an interface and cannot be constructed. Are you missing a type
mapping?
I can get around this by configuring it using code instead of xml:
container.RegisterType<IReader<Wrapper<Fund>>, WrappedFundReader>();
or I can create an interface that goes between and use that instead:
public interface IWrappedReader<T> : IReader<Wrapper<T>> { }
public class WrappedFundReader : IWrappedReader<Fund>
and the config would change to:
<register type="IWrappedReader[Fund]" mapTo="WrappedFundReader" />
It will still give me an instance that I can cast to IReader<Wrapper<Fund>>, but it seems like I should be able to make this work with the unity config.
What am I missing to make this work?
(If also tried creating specific aliases and wasn't able to get that to work either)
Aliasing worked for me...
<unity xmlns="http://schemas.microsoft.com/practices/2010/unity">
<alias alias="WrappedFund" type="TestUnityIssue.Wrapper`1[[TestUnityIssue.Fund, TestUnityIssue, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null]], TestUnityIssue, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null" />
<namespace name="TestUnityIssue" />
<assembly name="TestUnityIssue" />
<container>
<register type="IReader[Fund]" mapTo="FundReader" />
<register type="IReader[WrappedFund]" mapTo="WrappedFundReader" />
</container>
</unity>
these both resolved...
var fundReader = container.Resolve<IReader<Fund>>();
var wrappedReader = container.Resolve<IReader<Wrapper<Fund>>>();
and depending on your situation, you may be able to get away with less than the full AssemblyQualifiedName...
<alias alias="WrappedFund" type="TestUnityIssue.Wrapper`1[[TestUnityIssue.Fund, TestUnityIssue]], TestUnityIssue" />
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With