У меня есть несколько бизнес-классов, которые реализуют IBusinessRequest<T>
, например:
public class PersonBusiness : IBusinessRequest<Person>
{ }
Помимо этого у меня есть функция:
TypeHelper.CreateBusinessInstance(Type businessType, Type businessRequestType)
Требование бизнес-класса состоит в том, что у них должен быть конструктор без параметров, который я проверяю в функции TypeHelper.CreateBusinessInstance
.
Я хочу создать экземпляр типа businessType (который является PersonBusiness
) с общим значением businessRequestType
для IBusinessRequest<>
.
Как мне это сделать?
EDIT1:
Спасибо за все ответы, это поставило меня на правильный путь. Ситуация, которую я записал, не была реальной ситуацией, с которой я имел дело. Я надеялся, что этого было достаточно, чтобы решить мою проблему: -)
Теперь я придумал следующее, которое работает как шарм.
public interface IBusinessRequest<T> where T : class
{
T Request { get; set; }
}
public interface IBusiness
{
/// <summary>
/// Validates the request against custom rules
/// </summary>
/// <param name="meldingen">Return a list of validation messages</param>
/// <returns>returns true is validation went succesfull, false when something is wrong</returns>
bool Validate(out List<string> meldingen);
/// <summary>
/// Executes business logic and returns a response object.
/// </summary>
/// <returns>The strongly typed response object</returns>
object Execute(object request);
}
public class PersonBusiness :IBusiness, IBusinessRequest<Person>
{ }
public static IBusiness CreateBusinessInstance(Type type, object requestMessage)
{
//some checks on the type, like: is of IBusiness & IBusinessRequest<>
...
//get al constructors of type
ConstructorInfo[] constructors = type.GetConstructors();
//if we have more then one constructor throw error
if (constructors.Length > 1)
{
throw new BusinessCreateException(String.Format(PrivateErrors.ToManyConstructorsInTypeError, type, constructors.Length, 1));
}
//constructor parameters
ParameterInfo[] parameterInfo = constructors[0].GetParameters();
//we do not allow a constructor with more then one parameters.
if (parameterInfo.Length > 0)
{
throw new BusinessCreateException(String.Format(PrivateErrors.ConstructorHasToManyParametersError, type, 0));
}
IBusiness instance = null;
try
{
//create an instance, invoke constructor with zero parameters
object invokeResult = constructors[0].Invoke(new object[0]);
//set property "Request"
PropertyInfo pi = type.GetProperty("Request");
//do we have found a property
if (pi != null)
{
pi.SetValue(invokeResult, requestMessage ,null);
}
instance = invokeResult as IBusiness;
}
catch (Exception ex)
{
throw new BusinessCreateException(String.Format(PrivateErrors.BusinessCreateError, type.FullName), ex);
}
//return result
return instance;
}
Теперь во время выполнения в другой части программного обеспечения мне присваивается тип бизнес-класса (т.е. PersonBusiness). Другим фактом является то, что я знаю, что requestMessage является тем же, что и IBusinessRequest. Мне нужно это requestMessage для установки свойства Request класса PersonBusiness (который реализован из IRequestMessage)
Эти две переменные я передаю статическому IBusiness CreateBusinessInstance (тип Type, object requestMessage), который возвращает мне IBusiness, который я далее использую для выполнения некоторой бизнес-функции.
Спасибо всем!
Gr
Мартейн