[英]C# Instantiate class which implements generic interface
我有一些實現IBusinessRequest<T>
業務類,例如:
public class PersonBusiness : IBusinessRequest<Person>
{ }
除此之外,我還有一個功能:
TypeHelper.CreateBusinessInstance(Type businessType, Type businessRequestType)
業務類的要求是它們必須具有無參數構造函數,我在TypeHelper.CreateBusinessInstance
函數中檢查了該TypeHelper.CreateBusinessInstance
函數。
我想為IBusinessRequest<>
創建一個具有通用值businessRequestType
的類型businessType(即PersonBusiness
)的實例。
我該怎么做?
編輯1:
感謝您的所有回答,這使我步入正軌。 我寫下的情況不是我要處理的真實情況。 我希望這足以解決我的問題:-)
我現在想出了以下內容,它的作用就像魅力一樣。
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(類型類型,對象requestMessage),該變量將IBusiness退還給我,我又將其用於執行某些業務功能。
謝謝大家!
GR
馬丁
您的問題尚不清楚。 通常,對於要使用無參數構造函數創建新實例的泛型,可以使用new()
約束:
public interface IBusinessRequest<T> where T : new()
然后,您可以在IBusinessRequest<T>
的實現中使用new T()
。 無需親自檢查-編譯器會進行檢查。
但是,尚不清楚這是否是您真正想要的。 “具有IBusiness<>
的通用值businessRequestType
”是什么意思?
您可以使用兩個通用類型參數創建一個通用方法-一個用於業務請求類型,一個用於實現類型:
public static IBusinessRequest<T> CreateBusinessInstance<T, TImpl>() where TImpl : IBusinessRequest<T>, new()
{
return new TImpl();
}
您的示例將使用以下代碼:
IBusinessRequest<Person> request = CreateBusinessInstance<Person, PersonBusiness>();
嘗試這個:
Type[] typeArgs = { typeof(businessRequestType) };
return businessType.GetType.MakeGenericType(typeArgs);
給定Person類型時,是否要創建PersonBusiness實例?
var typeMap = new Dictionary<Type, Func<object>>
{
{ typeof(Person), () => new PersonBusiness() }
};
var businessInstance = (IBusinessRequest<Person>)typeMap[typeof(Person)]();
請參閱: 如何使用反射動態創建通用C#對象?
編輯2:實際上不需要businessRequestType
的參數。 根據定義, businessType
類型將實現IBusinessRequest <>的單一形式,因此無需傳遞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;
}
或者,您可以使用另一種通用方法:
IBusinessRequest<T> CreateBusinessInstance<T>(T businessType) where T : new() {
}
您可能需要在設計時知道類型,但這可能很好(不完全了解您的要求)...
歡呼馬蒂亞斯
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;
您可以繼承基類的方式,也可以調用TModel類型
希望這個幫助
菊
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.