【问题标题】:Creating Custom Container Class in c#在 C# 中创建自定义容器类
【发布时间】:2016-04-20 16:43:01
【问题描述】:

我正在为自定义 IOC 容器编写一个基本的 c# 类,其中包含两个公共方法 Register() 和 Resolve() 以及一个私有方法 CreateInstance()

下面是我的代码。

在下面的代码 CreateInstance() 方法中,我遇到语法错误来解决依赖关系(注释行),不使用泛型我可以解决依赖关系并且它工作正常,同时使用泛型进行默认类型转换我是出现语法错误

谁能帮我解决这条评论线?

  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);
    }
}

【问题讨论】:

  • “我遇到语法错误”什么错误?
  • The type arguments for method 'System.Linq.Enumerable.Select&lt;TSource,TResult&gt;(System.Collections.Generic.IEnumerable&lt;TSource&gt;, System.Func&lt;TSource,TResult&gt;)' cannot be inferred from the usage. Try specifying the type arguments explicitly.
  • 您的代码来源似乎是this answer,但您从该帖子中删除了非泛型GetInstance(Type) 方法。
  • 请注意该答案中给出的建议:“请注意,您永远不应实际使用此类实现。它缺少 DI 库为您提供的许多重要功能,但与使用纯 DI (即手工连接对象图)。你失去了编译时支持,没有得到任何回报。”。因此,除了学习目的之外,不要将该代码用于其他任何目的。在生产中使用 Pure DI 或已建立的 DI 库。
  • 无法从用法中推断出方法“Enumerable.Select(IEnumerable, Func)”的类型参数。尝试明确指定类型参数。我不确定如何在 select 方法中将动态类型传递给 Resolve() 函数

标签: c# .net dependency-injection inversion-of-control


【解决方案1】:

我知道这是不久前的一篇文章,但是如果有人想知道他们如何动态传递类型,您可以使用以下代码通过反射来完成:

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

这将找到 Resolve 方法,使用参数类型作为它的泛型类型,然后不带参数地调用它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-03-08
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多