繁体   English   中英

C#实例化类,实现通用接口

[英]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.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM