You'd think that an InjectionFactory would be the way to go. This compiles:
container.RegisterType<IQueryFactory>(new ContainerControlledLifetimeManager(),
new InjectionFactory((c, x, o) => new QueryFactory(t => c.Resolve(x))));
The problem is that the type x is always IQueryFactory so that doesn't get the results you want which is to return an IQuery.
Unfortunately, I don't think the current design fits with Unity very well.
However, with some slight modifications you can get the factory working. There are a few different ways of doing this (e.g. you could inject the container in the factory and resolve from there) however in this example I'll use a dictionary.
First we change the factory definition:
public class QueryFactory : IQueryFactory
{
private readonly IDictionary<Type, Func<IQuery>> _factoryQueries;
public QueryFactory(IDictionary<Type, Func<IQuery>> factoryQueries)
{
this._factoryQueries = factoryQueries;
}
public T ResolveQuery<T>() where T : class, IQuery
{
return this._factoryQueries[typeof(T)]() as T;
}
Basically, the Func<Type, object> resolveCallback
is swapped for an IDictionary containing Funcs for creating all supported IQuery types.
Next register the IDictionary and the IQueryFactory:
IUnityContainer container = new UnityContainer();
// Register all IQuery's
container.RegisterType<IActiveUsersQuery, ActiveUsersQuery>();
container.RegisterType<IUserByEmailQuery, UserByEmailQuery>();
IDictionary<Type, Func<IQuery>> factoryQueries = new Dictionary<Type, Func<IQuery>>()
{
{ typeof(IActiveUsersQuery), () => container.Resolve<IActiveUsersQuery>() },
{ typeof(IUserByEmailQuery), () => container.Resolve<IUserByEmailQuery>() },
};
// Register mapping
container.RegisterInstance<IDictionary<Type, Func<IQuery>>>(factoryQueries);
container.RegisterType<IQueryFactory, QueryFactory>();
var factory = container.Resolve<IQueryFactory>();
factory.ResolveQuery<IActiveUsersQuery>().Execute();
factory.ResolveQuery<IActiveUsersQuery>().Execute();
As mentioned, a simpler QueryFactory approach that takes a dependency on the container is:
public class QueryFactory : IQueryFactory
{
private readonly IUnityContainer container;
public QueryFactory(IUnityContainer container)
{
this.container = container;
}
public T ResolveQuery<T>()
where T : class, IQuery
{
return this.container.Resolve(typeof(T)) as T;
}
}
However, some would object to having the factory depend on the container implementation.
Another approach would be to get rid of the factory approach and inject the queries directly; this would make the dependencies obvious but I can see the scenario where you would want to dynamically get a query based on the command type. Also, I've seen relations between commands and queries which could be handled with open generics resolved in the composition root.