![](/img/trans.png)
[英]How to find namespace of class by its name using reflection in .net core?
[英]Find class to instantiate by name without namespace or assembly? (.NET)
我想通過名稱(字符串)實例化一個類而不指定名稱空間或程序集。 像這樣(Unity語法):
var processor = container.Resolve<IProcessor>("SpecialProcessor");
將實例化它找到的第一個IProcessor,稱為SpecialProcessor。 也許
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();
}
聽起來您具有插件體系結構,並且您希望允許其他組件提供IProcessor
實現,而不必更新某些主配置文件。 如果是這樣,那么我認為您最適合使用MEF(托管可擴展性框架)( 網站 )。
這是一個旨在允許此類行為的框架。 一旦建立了要從中加載組件的程序集目錄,導入IProcessor
實例的集合就很容易,如下所示
var processors = container.GetExportedValues<IProcessor>();
在線上有許多MEF教程可以幫助您入門。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.