我有一些实现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来设置PersonBusiness类的属性Request(从IRequestMessage实现)
我给静态IBusiness CreateBusinessInstance(Type type,object requestMessage)这两个变量,它给了我IBusiness,我进一步用它来执行一些业务功能。
全部谢谢!
的Gr
马亭
答案 0 :(得分:4)
你的问题有点不清楚。通常对于要使用无参数构造函数创建新实例的泛型,使用new()
约束:
public interface IBusinessRequest<T> where T : new()
然后,您可以在new T()
的实施中使用IBusinessRequest<T>
。无需自己检查 - 编译器会这样做。
然而,目前尚不清楚这是否真的是你在这里所追求的。您对“businessRequestType
”的通用值IBusiness<>
是什么意思?
答案 1 :(得分:3)
您可以使用两个泛型类型参数创建一个泛型方法 - 一个用于业务请求类型,另一个用于实现类型:
public static IBusinessRequest<T> CreateBusinessInstance<T, TImpl>() where TImpl : IBusinessRequest<T>, new()
{
return new TImpl();
}
你的例子会像这样使用它:
IBusinessRequest<Person> request = CreateBusinessInstance<Person, PersonBusiness>();
答案 2 :(得分:2)
试试这个:
Type[] typeArgs = { typeof(businessRequestType) };
return businessType.GetType.MakeGenericType(typeArgs);
答案 3 :(得分:1)
在给定Person类型时,您是否尝试创建PersonBusiness实例?
var typeMap = new Dictionary<Type, Func<object>>
{
{ typeof(Person), () => new PersonBusiness() }
};
var businessInstance = (IBusinessRequest<Person>)typeMap[typeof(Person)]();
答案 4 :(得分:1)
请参阅:How to dynamically create generic C# object using reflection?
编辑2:实际上不需要businessRequestType
中的参数。根据定义,类型businessType
将实现单一形式的IBusinessRequest&lt;&gt;所以没有必要通过businessRequestType
。相应地修改了解决方案。
编辑1:问题仍然有点令人困惑。我认为问题比你想要的更受限制。需要定义businessType和businessRequestType的所有组合。您可以使用分层对象工厂的某些变体,例如:
// Creates an instance of T that implements IBusinessRequest<R>
public static IBusinessRequest<R> CreateBusinessInstance<T, R>() where T :
IBusinessRequest<R>
{
return Activator.CreateInstance<T>();
}
// Creates an instance of businessType that implements
// IBusinessRequest<businessRequestType>
public static object CreateBusinessInstance(Type businessType)
{
object biz = null;
if (typeof(PersonBusiness) == businessType)
{
biz = CreateBusinessInstance<PersonBusiness, Person>();
}
//else if ... other business types
if (null == biz)
{
throw new ApplicationException("Unknown type");
}
return biz;
}
答案 5 :(得分:0)
或者你可以使用另一种通用方法:
IBusinessRequest<T> CreateBusinessInstance<T>(T businessType) where T : new() {
}
您需要在设计时知道类型,但这可能没问题(完全不了解您的要求)......
干杯 的Matthias
答案 6 :(得分:0)
public class GridController<TModel> : Web.Controllers.ControllerBase where TModel : new()
{
public ActionResult List()
{
// Get the model (setup) of the grid defined in the /Models folder.
JQGridBase gridModel = new TModel() as JQGridBase;
此方式您可以从基类继承并调用T模型类型
希望这个帮助
JU。