Tôi muốn khởi tạo một lớp theo tên (chuỗi) mà không chỉ định không gian tên hoặc tập hợp. Như thế này (Cú pháp Unity):
var bộ xử lý = container.Resolve("Bộ xử lý đặc biệt");
IProcessor đầu tiên mà nó tìm thấy có tên SpecialProcessor sẽ được khởi tạo. Có lẽ
MyNamespace. SpecialProcessor
Tôi muốn tránh phải tạo một mục trong cấu hình mỗi khi ai đó thêm bộ xử lý mới. Tuy nhiên, tôi hài lòng rằng tất cả các bộ ứng cử viên đều có một mục.
Tôi có thể sử dụng bộ chứa IoC để làm những việc như thế này hay tôi nên tự làm?
Đây là một chức năng thực hiện được rất nhiều điều bạn muốn. Bạn có thể dễ dàng sửa đổi điều này để lọc dựa trên tên lớp cụ thể.
Các hàm này tham chiếu một số tiện ích mà chúng tôi sử dụng để ghi nhật ký và xử lý ngoại lệ. Trong những trường hợp này, bạn cần thay thế chúng bằng những gì bạn thường làm.
tĩnh công khai T FindAndCreate(bool localOnly, bool chỉ xuất)
{
Loại [] loại = FindAssignableClasses(typeof(T), localOnly,exportOnly, false);
if (loại. Độ dài == 0)
{
trả về mặc định(T);
}
if (loại. Chiều dài != 1)
{
Log.Warn(typeof(ReflectionUtil),
"FindAndCreate đã tìm thấy {0} phiên bản của {1} trong khi dự kiến chỉ có 1 phiên bản. Sử dụng {2}. {3}",
các loại. Chiều dài,
typeof(T).FullName,
các loại[0].FullName,
String.Join("\r\n ", Array.ConvertAll(types, GetFullName)));
}
thử
{
return (T)Activator.CreateInstance(types[0]);
}
catch (Exception ex)
{
ném ExceptionUtil.Rethrow(ví dụ,
"Không thể tạo phiên bản của {0} được tìm thấy cho giao diện {1}.",
các loại[0].FullName,
typeof(T).FullName);
}
}
public static Type[] FindAssignableClasses(Loại có thể gán, bool localOnly, boolexportOnly, bool LoadDll)
{
var list = Danh sách mới();
chuỗi localDirectoryName = Path.GetDirectoryName(typeof(ReflectionUtil).Assembly.CodeBase);
if (loadDll && !_loadedAllDlls)
{
foreach (chuỗi dllPath trong Directory.GetFiles(localDirectoryName.Substring(6), "*.dll"))
{
thử
{
Assembly.LoadFrom(dllPath);
}
catch
{
// phớt lờ
}
}
_loadedAllDlls = true;
}
foreach (Assembly asm trong AppDomain.CurrentDomain.GetAssemblies())
{
thử
{
if (localOnly && Path.GetDirectoryName(asm.CodeBase) != localDirectoryName)
{
continue;
}
Loại [] loạiInAssembly;
thử
{
typeInAssembly = chỉ xuất khẩu asm.GetExportedTypes() : asm.GetTypes();
}
catch
{
continue;
}
foreach (Nhập t vào typeInAssembly)
{
thử
{
if (có thể gán.IsAssignableFrom(t) && có thể gán != t)
{
danh sách.Add(t);
}
}
catch (Exception ex)
{
Log.Debug(
typeof(ReflectionUtil),
String.Format(
"Lỗi tìm kiếm loại có thể gán cho loại {0} tìm kiếm lắp ráp {1} kiểm tra {2}{3}",
có thể gán.FullName,
asm.FullName,
t.FullName,
FlattenReflectionTypeLoadException(ex)),
ex);
}
}
}
catch (Exception ex)
{
// bỏ qua lỗi mô-đun động, không có cách nào để kiểm tra điều kiện này trước
// http://groups.google.com/group/microsoft.public.dotnet.lingu.csharp/browse_thread/thread/7b02223aefc6afba/c8f5bd05cc8b24b0
if (!(ví dụ là NotSupportedException && ex.Message.Contains("không được hỗ trợ ở dạng động")))
{
Log.Debug(
typeof(ReflectionUtil),
String.Format(
"Lỗi tìm kiếm loại có thể gán cho loại {0} tìm kiếm tập hợp {1} từ {2}{3}",
có thể gán.FullName,
asm.FullName,
asm.CodeBase,
FlattenReflectionTypeLoadException(ex)),
ex);
}
}
}
danh sách trả về.ToArray();
}
Tôi là một lập trình viên xuất sắc, rất giỏi!