У меня есть классы, которые являются производными от базового класса, и я хотел бы создать экземпляры этих классов динамически во время выполнения.Используя следующий код, я могу построить класс, используя конструктор по умолчанию:
public abstract class Employee : IEmployeeInterface
{
public string Name { get; set; }
public Employee() { }
public Employee(string name)
{
Name = name;
}
}
public static class EmployeeBot
{
static readonly Func<string, Func<Employee>> EmployeeBotFunction = x =>
Expression.Lambda<Func<Employee>>(
Expression.New(Type.GetType(x).GetConstructor(Type.EmptyTypes))
).Compile();
public static Employee InstantiateNewEmployee(string type)
{
string argumentType = string.Format("{1}.{0}", type.ToString(), MethodBase.GetCurrentMethod().DeclaringType.Namespace);
return EmployeeBotFunction(argumentType).Invoke();
}
}
Worker
реализует Employee
и может быть создан с использованием:
Employee employee = EmployeeBot.InstantiateNewEmployee("Worker");
Тогда, так как Worker
имеет все те же методы, что и Employee
, вызов их даст ожидаемые результаты из рабочего класса.
Однако я не могу понять, как правильно реализовать подобный код для использования конструктора с аргументами.Например:
static readonly Func<string, Type[], Func<string, Employee>> NewEmployee = (x, y) =>
Expression.Lambda<Func<string, Employee>>(
Expression.New(Type.GetType(x).GetConstructor(y))
).Compile();
public static Employee InstantiateNewEmployee(string type, string Name)
{
Type[] construct = new Type[] { typeof(string) };
string argumentType = string.Format("{1}.{0}", type.ToString(), MethodBase.GetCurrentMethod().DeclaringType.Namespace);
return NewEmployee(argumentType, construct).Invoke(Name);
}
Вызов этого метода вызывает исключение:
EmployeesTests.InstantiateEmployeeWithName выбросило исключение: System.InvalidOperationException: метод может быть вызван только для типа, для которого тип.IsGenericParameter имеет значение true.
Как можно изменить функцию NewEmployee
, чтобы принять необходимые параметры для второго конструктора?