c# - 查找要在没有命名空间或程序集的情况下按名称实例化的类? (。网)

标签 c# ioc-container

我想按名称(字符串)实例化一个类,而不指定命名空间或程序集。像这样(Unity 语法):

var processor = container.Resolve<IProcessor>("SpecialProcessor");

将实例化它找到的第一个称为 SpecialProcessor 的 IProcessor。也许

MyNamespace.SpecialProcessor

我希望避免每次有人添加新处理器时都必须在配置中创建一个条目。不过,我很乐意为所有候选人集会提供一个条目。

我可以使用 IoC 容器来做这样的事情还是我应该自己开发?

最佳答案

这是一个函数,它的功能与您想要的非常相似。您可以很容易地修改它以根据特定的类名进行过滤。

这些函数引用了我们用于日志记录和异常处理的一些实用程序。您需要将它们替换为您在这些情况下通常执行的操作。

    public static T FindAndCreate<T>(bool localOnly, bool exportedOnly)
    {
        Type[] types = FindAssignableClasses(typeof(T), localOnly, exportedOnly, false);
        if (types.Length == 0)
        {
            return default(T);
        }
        if (types.Length != 1)
        {
            Log.Warn(typeof(ReflectionUtil),
                     "FindAndCreate found {0} instances of {1} whereas only 1 was expected.  Using {2}.  {3}",
                     types.Length,
                     typeof(T).FullName,
                     types[0].FullName,
                     String.Join("\r\n  ", Array.ConvertAll<Type, String>(types, GetFullName)));
        }
        try
        {
            return (T)Activator.CreateInstance(types[0]);
        }
        catch (Exception ex)
        {
            throw ExceptionUtil.Rethrow(ex,
                                        "Unable to create instance of {0} found for interface {1}.",
                                        types[0].FullName,
                                        typeof(T).FullName);
        }
    }

    public static Type[] FindAssignableClasses(Type assignable, bool localOnly, bool exportedOnly, bool loadDll)
    {
        var list = new List<Type>();
        string localDirectoryName = Path.GetDirectoryName(typeof(ReflectionUtil).Assembly.CodeBase);

        if (loadDll && !_loadedAllDlls)
        {
            foreach (string dllPath in Directory.GetFiles(localDirectoryName.Substring(6), "*.dll"))
            {
                try
                {
                    Assembly.LoadFrom(dllPath);
                }
                catch
                {
                    // ignore
                }
            }
            _loadedAllDlls = true;
        }

        foreach (Assembly asm in AppDomain.CurrentDomain.GetAssemblies())
        {
            try
            {
                if (localOnly && Path.GetDirectoryName(asm.CodeBase) != localDirectoryName)
                {
                    continue;
                }

                Type[] typesInAssembly;
                try
                {
                    typesInAssembly = exportedOnly ? asm.GetExportedTypes() : asm.GetTypes();
                }
                catch
                {
                    continue;
                }

                foreach (Type t in typesInAssembly)
                {
                    try
                    {
                        if (assignable.IsAssignableFrom(t) && assignable != t)
                        {
                            list.Add(t);
                        }
                    }
                    catch (Exception ex)
                    {
                        Log.Debug(
                            typeof(ReflectionUtil),
                            String.Format(
                                "Error searching for types assignable to type {0} searching assembly {1} testing {2}{3}",
                                assignable.FullName,
                                asm.FullName,
                                t.FullName,
                                FlattenReflectionTypeLoadException(ex)),
                            ex);
                    }
                }
            }
            catch (Exception ex)
            {
                // ignore dynamic module error, no way to check for this condition first
                // http://groups.google.com/group/microsoft.public.dotnet.languages.csharp/browse_thread/thread/7b02223aefc6afba/c8f5bd05cc8b24b0
                if (!(ex is NotSupportedException && ex.Message.Contains("not supported in a dynamic")))
                {
                    Log.Debug(
                        typeof(ReflectionUtil),
                        String.Format(
                            "Error searching for types assignable to type {0} searching assembly {1} from {2}{3}",
                            assignable.FullName,
                            asm.FullName,
                            asm.CodeBase,
                            FlattenReflectionTypeLoadException(ex)),
                        ex);
                }
            }
        }

        return list.ToArray();
    }

关于c# - 查找要在没有命名空间或程序集的情况下按名称实例化的类? (。网),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2159879/

相关文章:

c# - 比较 Entity Framework 4.1 中 Any() 与 Count() 生成查询的性能

c# - 从 .Net Standard 项目和 Native dll 创建一个 nuget 包

c# - 通过上下文解决依赖关系 - 深入解析树

c# - IOC 容器实际上为我做了什么?

c# - 为什么使用 JWT 时 UserManager.GetUserAsync 会返回 null?

c# - 为 COM Interop 注册 x64 程序集的问题

c# - 使用标识将集合添加到 ASP.NET Core 中的用户对象

asp.net-mvc - IoC CaSTLe Windsor - 没有为此对象定义无参数构造函数

c# - 简单注入(inject)器 - 使用一个自定义参数注册服务

c# - DI 容器是否需要自己实例化对象才能使用构造函数注入(inject)?