【问题标题】:Different Type instantiation at runtime in C#C# 运行时的不同类型实例化
【发布时间】:2018-04-19 17:31:45
【问题描述】:

我必须解决我需要为每种传感器类型进行不同计算的问题(我需要决定在运行时实例化哪种类型)。 让我举个例子:

1.从数据库表我得到这个结果:

SensorType RawValue ADCGain R0Value I0Value ABCValue 
1          100      0.1     NULL    NULL    NULL
1          150      0.2     NULL    NULL    NULL
2          30       NULL    1       2       2
2          15       NULL    5       5       6 

假设传感器类型 1 是具体类型 AISensor 并且继承自基类,类型 2 是 Pt100Tempsensor 并且继承自同一个基类。 这是 C# 中的类定义:

 public abstract class Sensor
     {
        public abstract int Id { get;  set; }
        public abstract string Code { get;  set; }
        public abstract string Name { get;  set; }

        public abstract double GetCalculatedValue(int rawValue);
    }

   public class Pt100Tempsensor : Sensor
    {

        public int R0Value { get; set; }
        public int I0value { get; set; }
        public int ABCValue { get; set; }
        public override int Id { get; set; }
        public override string Code { get; set; }
        public override string Name { get; set; }

        public override double GetCalculatedValue(int rawValue)
        {
            return ((R0Value * I0value) / ABCValue) * rawValue;
        }
    }

public class AISensor : Sensor
{
    public int AdcGain { get; set; }
    public override int Id { get; set; }
    public override string Code { get; set; }
    public override string Name { get; set; }

    public override double GetCalculatedValue(int rawValue)
    {
        return rawValue * AdcGain;
    }
}

现在我想知道在运行时实例化对象的最佳方法是什么,如果我添加新的传感器类型,我不需要更改现有代码(比如在简单的工厂方法“模式”中)。

感谢您的帮助。

【问题讨论】:

  • 是的,使用简单的工厂模式。

标签: c# inheritance polymorphism instantiation factory-pattern


【解决方案1】:

您可以使用 ORM(实体框架,NHibernate)来实现这一点。创建新的 Sensor 类时,必须修改代码,但仅限于数据库映射部分。

该表看起来像一个带有TPH 映射策略的表,其中 SensorType 是鉴别器列。

【讨论】:

  • 在从数据库中选择语句中,它看起来像一个 TPH 映射策略,但在底层数据库模型中,我打算将其实现为 TPT 模型。
  • 如果我想使用简单的方法工厂模式,我还需要基表中的某种鉴别器列,对吧?
  • 是的,您需要,但是您有 SensorType 列,它指示类型(鉴别器)。
  • 在 DB 模式中,基表看起来像这样(列):ID、代码、名称、SensorTypeId(鉴别器)。对吗?
  • 在TPT映射策略中,你并不需要一个鉴别列(例如ORM),因为表名表明了具体的类型。但是如果你不使用 ORM,你可能需要那个鉴别器列(SensorTypeId)来指示类型。
【解决方案2】:

我支持简单工厂模式的建议。

但是:如果你真的需要添加新的传感器不接触现有代码,我只能想到一个“插件系统”。这意味着:

  • 您有一个通用界面。
  • 您可以通过某种配置将 ID 映射到实现。
  • 您有一个可以检测实现并根据上述配置创建实例的工厂。

供参考:Microsoft 有一些示例代码。见https://code.msdn.microsoft.com/windowsdesktop/Creating-a-simple-plugin-b6174b62

【讨论】:

  • 如果我使用 autofac 那么实际上根本不需要使用简单的工厂模式吗?我会像这样在 ioc 容器中注册类型: ioc.RegisterType("1" );, ioc.RegisterType("2");
  • 我(还)不特别熟悉 autofac。我想应该有一种方法可以通过 DI 实现这种行为。唯一的问题是:您仍然需要以某种方式向 DI 框架注册实现。一旦我能得到一些信息,我会更新答案。
  • 好的,谢谢...是的,但您仍然需要更新 ioc 类型映射类/配置文件...
  • 看看这个:docs.autofac.org/en/latest/integration/mef.html 不确定它是否是你要找的。听起来像,虽然乍一看。
【解决方案3】:

最简单的方法是使用基于 ID 的开关的工厂方法,根据 ID 号制作不同的传感器。

如果您希望能够在不更改任何其他代码(即不更改工厂方法)的情况下添加传感器,那么您需要使用反射来 (1) 发现所有可用的传感器类型并 (2) 根据它的 ID。你可以用一个属性来做到这一点,例如:

[Sensor(42)]
public class Pt100Tempsensor : Sensor
{
    ....

其中 42 是 ID

但老实说,只有当您真的要拥有大量传感器类型时,才值得这样做。

【讨论】:

    【解决方案4】:

    使用根据传感器类型 ID 创建具体传感器的工厂

    【讨论】:

      猜你喜欢
      • 2011-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-19
      • 2019-05-20
      • 2017-02-06
      • 2022-07-27
      • 2017-11-08
      • 2010-11-02
      相关资源
      最近更新 更多