是否可以在Generic Type工厂中使用从字符串加载的类型? [英] Is it possible to use a type loaded from string in a Generic Type factory?

查看:57
本文介绍了是否可以在Generic Type工厂中使用从字符串加载的类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述





我为一些xml解析器类编写了一个工厂(每个供应商一个)。解析器类实现了一个接口,工厂只需调用解析器类方法。这是我的工厂类:



Hi,

I wrote a factory for some xml parser classes (one for each supplier). The parser classes implemented an interface and the factory would simply call the parser classes method. Here is my factory class:

public static class FlightDataFactory<T> where T : Interface.IFlightDataWorker, new()
{
    public static FlightData.Model.Flight GetFlightData(string flightId)
    {
        T t = new T();
        return t.GetFlightData(flightId);
    }
    public static List<FlightData.Model.Flight> GetFlightData()
    {
        T t = new T();
        return t.GetFlightData();
    }
}



我希望这一切都是自我解释的。



我现在需要从字符串中加载类,保存在供应商的db表中(原因是我们将产品化这个系统并且只希望包含与该客户端相关的解析器)。



我正在创建这样的解析器方法列表:


I hope that's all self explanatory.

I now need to load the classes from strings, kept in a db table of suppliers (The reason for this is that we will product-ize this system and only wish to include parsers that are relevant to that client).

I was creating the list of parser methods like this:

private void InitializeWorkers()
{
    flightWorkers = new[]{
        new Worker.FlightServiceWorker(){
            Source = "AirNav",
            GetFlightByIdMethod = FlightData.Factory.FlightDataFactory<FlightData.Worker.AirNavWorker>.GetFlightData,
            GetFlightsMethod = FlightData.Factory.FlightDataFactory<FlightData.Worker.AirNavWorker>.GetFlightData
        },
        new Worker.FlightServiceWorker(){
            Source = "AirNavMock",
            GetFlightByIdMethod = FlightData.Factory.FlightDataFactory<FlightData.Worker.AirNavMockWorker>.GetFlightData,
            GetFlightsMethod = FlightData.Factory.FlightDataFactory<FlightData.Worker.AirNavMockWorker>.GetFlightData
        }
    };
}





我的问题是:我可以像我一样从字符串加载类可以使用它们作为上面代码中的类型,或者我必须调用这些方法。



如果我必须调用它们,那么我想我的工厂是一个注销



谢谢。如果我可以在投票前改进我的问题,请告诉我^ _ ^



My question is: Can I load the classes from a string in such a way as I can use them as types as in the above code, or must I invoke the methods instead.

If I have to invoke them then I guess my factory is a write off

Thanks. Please let me know if I can improve my question before down-voting it ^_^

推荐答案

我用一个新的(但不那么整洁的)工厂解决了这个问题。



如果有人可以帮我整理一下那么我会很高兴





I solved this with a new (but not so neat) factory.

If anyone can help me tidy this up then I would be greatful


   public delegate FlightData.Model.Flight GetFlightById(string flightId);
   public delegate List<flightdata.model.flight> GetFlights();
public static class FlightDataFactory
   {
       public static GetFlightById GetFlightByIdDataMethod(Type iFlightDataWorker)
       {
           if (!iFlightDataWorker.GetType().GetInterfaces().Contains(typeof(Interface.IFlightDataWorker)))
               throw new ArgumentException(string.Format("The type {0} does not implement the interface {1}.", iFlightDataWorker.Name, typeof(Interface.IFlightDataWorker).Name), "iFlightDataWorker");

           object worker = iFlightDataWorker.GetConstructor(Type.EmptyTypes).Invoke(new object[]{});

           return delegate(string flightId)
           {
               return (FlightData.Model.Flight)iFlightDataWorker.GetMethod("GetFlightData").InvokeWithExceptions(worker, new object[] { flightId });
           };

       }
       public static GetFlights GetFlightDataMethod(Type iFlightDataWorker)
       {
           if (!iFlightDataWorker.GetType().GetInterfaces().Contains(typeof(Interface.IFlightDataWorker)))
               throw new ArgumentException(string.Format("The type {0} does not implement the interface {1}.", iFlightDataWorker.Name, typeof(Interface.IFlightDataWorker).Name), "iFlightDataWorker");

           object worker = iFlightDataWorker.GetConstructor(Type.EmptyTypes).Invoke(new object[] { });

           return delegate
           {
               return (List<flightdata.model.flight>)iFlightDataWorker.GetMethod("GetFlightData").InvokeWithExceptions(worker, new object[] { });
           };
       }
   }</flightdata.model.flight></flightdata.model.flight>





我还创建了一个方便的扩展方法,所以我已经过了targetinvocationexceptions,我希望不会这样做。



I have also created a handy Extension method so I get past targetinvocationexceptions which I would hope not to get.

public static object InvokeWithExceptions(this MethodInfo methodInfo, object obj, params object[] parameters)
{
    try
    {
        return methodInfo.Invoke(obj, parameters);
    }
    catch (TargetInvocationException exception)
    {
        if (exception.InnerException != null)
            throw exception.InnerException;
        throw;
    }
}


我认为使用依赖注入或反转控制容器会更好作为Microsoft的Unity,NInject,StructureMap或我的Munq IocContainer。



您使用容器注册接口实现,然后遵循依赖注入模式或服务定位器模式在需要时获取接口的实现。
I think you would be better served by using a Dependency Injection or Inversion of Control Container such as Microsoft's Unity, NInject, StructureMap, or my Munq IocContainer.

You register the Interface implementations with the container and then either follow the Dependency Injection pattern or Service Locator pattern to get the implementation for the Interface when required.


这篇关于是否可以在Generic Type工厂中使用从字符串加载的类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆