Is it possible to create a Func
that has a generic T
as runtime parameter?
I'm using Func
to create some instances that are using generics. I would like to do something like this:
var myFunc = new Func<IEnumerable<T>>(x => new List<T>());
IEnumerable<string> result = myFunc<string>();
IEnumerable<int> result2 = myFunc<int>();
IEnumerable<Bar> result3 = myFunc<Bar>();
But it obviously doesn't compile because T
is unknown at this moment. The code below will compile, but it will not work in my case since I need the strongly typed List<T>
.
var func = new Func<IList>(() => new ArrayList());
If it's not possible with Func
, is it possible with Expression
or delegates
?
For background info I can say that I'm using this as part of a factory pattern together with Unity IoC. I'm building on this example: Unity auto-factory with params.
EDIT: I realise that my question was poorly asked. Sorry for that. I tried to keep the question simple by not including the background (purpose). The whole point is that I'm using Unity as IoC and have a factory that looks like this:
public interface ICollectionWrapperFactory
{
ICollectionWrapper<T> CreateCollection<T>(IEnumerable<T> items);
}
public class CollectionWrapperFactory :ICollectionWrapperFactory
{
private readonly IUnityContainer _container;
public CollectionWrapperFactory(IUnityContainer container)
{
_container = container;
}
public ICollectionWrapper<T> CreateCollection<T>(IEnumerable<T> items)
{
ICollectionWrapper<T> collectionWrapper;
if (items == null)
{
collectionWrapper = _container.Resolve<ICollectionWrapper<T>>(new ParameterOverride("items", new T[0]));
}
else
{
collectionWrapper = _container.Resolve<ICollectionWrapper<T>>(new ParameterOverride("items", items));
}
return collectionWrapper;
}
}
It is using the IUnityContainer
to resolve the instance. But I want to remove the dependency to IUnityContainer
from the implementation because of the service locator anti-pattern. Instead I want to do something like this:
public class CollectionWrapperFactory :ICollectionWrapperFactory
{
private readonly Func<IEnumerable<T>, ICollectionWrapper<T>> _createFunc;
public CollectionWrapperFactory(Func<IEnumerable<T>, ICollectionWrapper<T>> createFunc)
{
_createFunc = createFunc;
}
public ICollectionWrapper<T> CreateCollection<T>(IEnumerable<T> items)
{
ICollectionWrapper<T> collectionWrapper;
if (items == null)
{
collectionWrapper = _createFunc(new T[0]);
}
else
{
collectionWrapper = _createFunc(items);
}
return collectionWrapper;
}
}
public class CollectionWrapper<TModel> : ICollectionWrapper<TModel>
{
private IEnumerable<TModel> _items;
public CollectionWrapper(IEnumerable<TModel> items)
{
_items = items;
TotalCount = items.Count();
}
public int TotalCount { get; set; }
public IEnumerable<TModel> Items
{
get { return _items; }
set { _items = value; }
}
}
And in my registration:
container.RegisterType<ICollectionWrapperFactory, CollectionWrapperFactory>(
new ContainerControlledLifetimeManager(),
new InjectionConstructor(
new Func<IEnumerable<T>, ICollectionWrapper<T>>(
items => container.Resolve<ICollectionWrapper<T>>(new ParameterOverride("items", items)))));
container.RegisterType(typeof(ICollectionWrapper<>), typeof(CollectionWrapper<>), new TransientLifetimeManager());
This way I will remove the dependency to IUnityContainer from the implementation and thus the service locator anti-pattern (I guess?). Instead I need to inject the func to create the instance, but I don't know how to inject a func with a generic parameter.
Good examples for exactly what I want, but with generics: