1

I'm writing a basic c# class for custom IOC container with two Public methods Register() & Resolve() and one private Method CreateInstance()

below is my code.

In the below Code, CreateInstance() method, i'm getting syntax error to Resolve the dependencies (commented line), without using Generics I could resolve the dependencies and it works fine, while using generics for default typecasting I'm getting syntax error

Can anyone help me on this Commented Line?

  public class Container
  {
    static Dictionary<Type, Func<object>> registrations = new Dictionary<Type, Func<object>>();
    public static void Register<TService, TImpl>() where TImpl : TService
    {
        registrations.Add(typeof(TService), () => Resolve<TImpl>());
    }

    public static T Resolve<T>()
    {
        var serviceType = typeof(T);
        Func<object> creator;
        if (registrations.TryGetValue(serviceType, out creator)) return (T)creator();
        if (!serviceType.IsAbstract) return CreateInstance<T>();
        else throw new InvalidOperationException("No registration for " + serviceType);
    }

    private static T CreateInstance<T>()
    {
        var implementationType = typeof(T);
        var ctor = implementationType.GetConstructors().Single();
        var parameterTypes = ctor.GetParameters().Select(p => p.ParameterType);        
        //var dependencies = parameterTypes.Select(Resolve).ToArray();            
        return (T)Activator.CreateInstance(implementationType, dependencies);
    }
}
Mathiyazhagan
  • 1,389
  • 3
  • 13
  • 37
  • 1
    "i'm getting syntax error" what error? – Steven Apr 20 '16 at 17:37
  • `The type arguments for method 'System.Linq.Enumerable.Select(System.Collections.Generic.IEnumerable, System.Func)' cannot be inferred from the usage. Try specifying the type arguments explicitly.` – Corak Apr 20 '16 at 17:40
  • 1
    The source of your code seems to be [this answer](https://stackoverflow.com/questions/15715978/simple-dependency-resolver/15717047#15717047), but you removed the non-generic `GetInstance(Type)` method from that post. – Steven Apr 20 '16 at 17:40
  • Be warned about the advise given in that answer: "Please note that you should never actually use such implementation. It lacks many important features that DI libraries give you, yet gives no advantage over using Pure DI (i.e. hand-wiring object graphs). You loose compile-time support, without getting anything back.". So don't use that code for anything else but learning purposes. Use either [Pure DI](http://blog.ploeh.dk/2014/06/10/pure-di/) or an established DI library in production. – Steven Apr 20 '16 at 17:42
  • The type arguments for method 'Enumerable.Select(IEnumerable, Func)' cannot be inferred from the usage. Try specifying the type arguments explicitly. I'm not sure how to pass the dynamic Type to Resolve<>() func inside the select method – Mathiyazhagan Apr 20 '16 at 17:43
  • @Steven Yes, you are Partially correct. I renamed the GetInstance() method to Resolve(), and the problem in the post is it always returns object type, which i need to typecast everywhere in my code. So i want to change the GetInstance() method return the Interface type instead of Object Type – Mathiyazhagan Apr 20 '16 at 17:49
  • You need both a generic `Resolve` and a non-generic `Resolve(Type)` for this to work. The fact however that you seem to "need to typecast everywhere in my code" is an indication that you are abusing the container as a Service Locator; which is something you should [absolutely not do](http://blog.ploeh.dk/2010/02/03/ServiceLocatorisanAnti-Pattern/). – Steven Apr 20 '16 at 18:18

1 Answers1

1

I know this is a post from a while ago however if anyone is wondering how they could dynamically pass a type you can do it with reflection using the code below:

        var dependencies = parameterTypes.Select(paramType => typeof(Container).GetMethod("Resolve")?.MakeGenericMethod(paramType).Invoke(null, null)).ToArray();            

This will find the Resolve method, use the parameter type as it's generic type, and then invoke it with no arguments.

CameronL
  • 11
  • 2