通用实体的相同服务基类

时间:2015-05-15 22:36:08

标签: c# generics

我实现了一些将特定类型转换为字节数组的转换器类,反之亦然。 此转换器将注入包含其他信息的实体。

我还实现了一些特定的实体服务,这些服务根据存储在实体类中的信息来完成。

问题是我需要x种不同的服务来处理所有可能的实体对象。有没有办法在不指定转换器类型的情况下实例化服务?

转换器类:

abstract class Converter<TValue>
{
    public abstract byte[] ConvertFromValue(TValue value);
    public abstract TValue ConvertToValue(byte[] value);
}

class DoubleConverter : Converter<double>
{
    public double Coefficient { get; private set; }
    public DoubleConverter(double coefficient) { Coefficient = coefficient; }
    public override byte[] ConvertFromValue(double value) { return BitConverter.GetBytes(value * Coefficient); }
    public override double ConvertToValue(byte[] value) { return BitConverter.ToDouble(value, 0) / Coefficient; }
}

class StringConverter : Converter<string>
{
    public Encoding Encoding { get; private set; }
    public StringConverter(Encoding encoding) { Encoding = encoding; }
    public override byte[] ConvertFromValue(string value) { return Encoding.GetBytes(value); }
    public override string ConvertToValue(byte[] value) { return Encoding.GetString(value); }
}

使用转换器的实体:

abstract class Base<TValue>
{
    protected Converter<TValue> Converter;
    public Base(Converter<TValue> converter) { Converter = converter; }
    public byte[] Convert(TValue value) { return Converter.ConvertFromValue(value); }
}

class Foo<TValue> : Base<TValue>
{
    public string Id { get; private set; }
    public Foo(string id, Converter<TValue> converter) : base(converter) { Id = id; }
}

class Bar<TValue> : Base<TValue>
{
    public Bar(Converter<TValue> converter) : base(converter) { }
}

做东西的实体服务:

abstract class Service<TValue, TBase>
    where TBase : Base<TValue>
{
    public abstract void Do(TBase entity, TValue value);
}

class FooService<TValue> : Service<TValue, Foo<TValue>>
{
    public override void Do(Foo<TValue> entity, TValue value) {/* Foo specific stuff */}
}

class BarService<TValue> : Service<TValue, Bar<TValue>>
{
    public override void Do(Bar<TValue> entity, TValue value) {/* Bar specific stuff */}
}

问题是我必须根据使用的不同类型转换器创建FooService n次。

var twice = new DoubleConverter(2);
var half = new DoubleConverter(0.5);
var str = new StringConverter(Encoding.ASCII);

var foo1 = new Foo<double>("Twice Foo", twice);
var foo2 = new Foo<string>("String Foo", str);
var bar = new Bar<double>(half);

var fooService = new FooService(); // requires 1 type argument
var barService = new BarService(); // requires 1 type argument

fooService.Do(foo1, 13.4);
fooService.Do(foo2, "123456");
barService.Do(bar, 1.1);

1 个答案:

答案 0 :(得分:0)

将服务作为实体内的方法移动:

abstract class Base<TValue>
{
    protected Converter<TValue> Converter;
    public Base(Converter<TValue> converter) { Converter = converter; }
    public byte[] Convert(TValue value) { return Converter.ConvertFromValue(value); }
    public abstract void DoService(TValue value);
}

class Foo<TValue> : Base<TValue>
{
    public string Id { get; private set; }
    public Foo(string id, Converter<TValue> converter) : base(converter) { Id = id; }
    public override void DoService(TValue value) {/* Foo specific stuff */}
}

class Bar<TValue> : Base<TValue>
{
    public Bar(Converter<TValue> converter) : base(converter) { }
    public override void DoService(TValue value) {/* Bar specific stuff */}
}

然后用法就像:

        DoubleConverter twice = new DoubleConverter(2);
        DoubleConverter half = new DoubleConverter(0.5);
        StringConverter str = new StringConverter(Encoding.ASCII);

        Foo<double> foo1 = new Foo<double>("Twice Foo", twice);
        Foo<string> foo2 = new Foo<string>("String Foo", str);
        Bar<double> bar = new Bar<double>(half);

        foo1.DoService(13.4);
        foo2.DoService("123456");
        bar.DoService(1.1);