C# 在处理web请求时使用可靠的方法

C# 在处理web请求时使用可靠的方法,c#,solid-principles,C#,Solid Principles,我目前正在开发一个服务结构解决方案,其中数据从一个服务发送到下一个服务 我正在发送带有几个属性的类。此类是一种数据传输对象。我想使用一种可靠的方法来防止使用导致开关逻辑的整数 我不想要这个: public void ExecuteFunctionForType(IntegerTypedClass myClass, IInterface myinterface) { switch(myClass.typeInt) { case 1: // D

我目前正在开发一个服务结构解决方案,其中数据从一个服务发送到下一个服务

我正在发送带有几个属性的类。此类是一种数据传输对象。我想使用一种可靠的方法来防止使用导致开关逻辑的整数

我不想要这个:

public void ExecuteFunctionForType(IntegerTypedClass myClass, IInterface myinterface)
{
    switch(myClass.typeInt)
    {
        case 1:
            // Do shizzle for type 1
            myinterface.execute1();
            break;
        case 2:
            // do shizzle for type 2
            myinterface.execute2();
            break;
    }
}
相反,我希望实施一种可靠的方法。我想到的一个例子如下所示:

public abstract class AbstractTypedClass
{
    public abstract void ExecuteInheritedFunction(IInterface myinterface);
}

public class FirstTypedClass : AbstractTypedClass
{
    public override void ExecuteInheritedFunction(IInterface myinterface)
    {
        // do shizzle for the first typed class
        myinterface.execute1();
    }
}

public class SecondTypedClass : AbstractTypedClass
{
    public override void ExecuteInheritedFunction(IInterface myinterface)
    {
        // do shizzle for the second typed class
        myinterface.execute2();
    }
}
这种方法的问题是,
AbstractTypedClass
及其所有子类都将依赖于
IInterface
,这是我不想要的。这是因为它是一个服务结构接口,它带来了许多其他依赖项。 我更希望有一个解决方案,您可以使用solid原则,而不是创建对不同库的依赖,这将使我的解决方案变得混乱

我不能使用的东西:

分部类,因为它们需要在同一个assemvly中

扩展方法,因为会调用默认方法:

public static class TypedClassExtensions
{
    public static void executeExtension(this AbstractTypedClass request, IInterface myinterface)
    {
        throw new NotImplementedException();
    }
    public static void executeExtension(this FirstTypedClass request, IInterface myinterface)
    {
        myinterface.execute1();
    }
}

// when calling the code like so, the not implemented exception is thrown:
public void execute(AbstractTypedClass myclass, IInterface myinterface)
{
    myclass.executeExtension(myinterface);
}
在C#7中,可以使用模式匹配来避免使用策略或访问者模式。这会产生更干净的代码,因为您不必向所有具体类添加相同的方法,也不必使用双重分派

void ExecuteFunctionForType(AbstractTypedClass myClass, IInterface myinterface)
{
    switch(myClass)
    {
        case FirstTypedClass it1:
            // Do shizzle for type 1
            myinterface.execute1(it1.Prop1);
            break;
        case SecondTypedClass it2:
            // do shizzle for type 2
            myinterface.execute2(it2.Prop2);
            break;
    }
}
假设接口和实现如下所示:

interface IInterface {void execute1(string input);void execute2(int input);}

class SomeClass:IInterface
{
    public void execute1(string input) => Console.WriteLine($"1 {input}");
    public void execute2(int    input) => Console.WriteLine($"2 {input}");
}
像这样的课程:

public abstract class AbstractTypedClass{    }

public class FirstTypedClass : AbstractTypedClass
{
    public string Prop1 =>"First";
}

public class SecondTypedClass : AbstractTypedClass
{
    public int Prop2 =>500;
}
可以使用对类型执行模式匹配的switch语句为每个类型调用不同的方法。以下代码:

var it=new SomeClass();
ExecuteFunctionForType(new FirstTypedClass(),it);
ExecuteFunctionForType(new SecondTypedClass(),it);
将产生:

1 First
2 500

类型上的模式匹配返回匹配类型的强类型变量。可以使用每种具体类型的成员,而无需对接口或抽象类进行定义。

使用可靠原则,我认为您的方法如下所示:

interface IInterface {void execute1(string input);void execute2(int input);}

class SomeClass:IInterface
{
    public void execute1(string input) => Console.WriteLine($"1 {input}");
    public void execute2(int    input) => Console.WriteLine($"2 {input}");
}
依赖倒置原则建议您只依赖于函数所需的接口。因此,在您的抽象类上,我将简单地使其通用,并在抽象类的实现中定义依赖项。这样,如果您可以在不同的程序集中实现不同的版本,并且这些程序集不会有不必要的依赖关系

// ------------ Assembly A -----------------
public abstract class AbstractTypedClass<T>
{
    public abstract void ExecuteInheritedFunction(T obj);
}

// ------------ Assembly B -----------------
IHugeDependency
{
    void execute1();
    ...more
}

public class FirstTypedClass : AbstractTypedClass<IHugeDependency>
{
    public override void ExecuteInheritedFunction(IHugeDependency obj)
    {
        // do shizzle for the first typed class
        obj.execute1();
    }
}

// ------------ Assembly C -----------------
ISmallerDependency
{
    void execute2();
}

public class SecondTypedClass : AbstractTypedClass<ISmallerDependency>
{
    public override void ExecuteInheritedFunction(ISmallerDependency obj)
    {
        // do shizzle for the second typed class
        obj.execute2();
    }
}
/--------------组件A-----------------
公共抽象类AbstractTypedClass
{
公共抽象无效执行指定函数(T obj);
}
//------组件B-----------------
我觉得依赖
{
void execute1();
更多
}
公共类FirstTypedClass:AbstractTypedClass
{
公共覆盖无效ExecuteInheritedFunction(iHugeDependence obj)
{
//第一节课上你一定要迟到
obj.execute1();
}
}
//------组件C-----------------
非对称性
{
void execute2();
}
公共类SecondTypedClass:AbstractTypedClass
{
公共覆盖无效ExecuteInheritedFunction(ISmallerDependence obj)
{
//不要为第二节课感到恶心
obj.execute2();
}
}

使用这种方法,组件B和C都依赖于a,但B&C没有任何理由彼此依赖。

试试策略模式不是我刚才描述的策略吗?如果我使用这种策略,我仍然会被界面的依赖性所困扰。我正在寻找一种方法,以消除依赖向我们展示您所需的设计输出。它不必工作。。只是想了解一下。因为你说过你不想要
接口
依赖关系。你可以通过模式匹配来避免这一切。我们已经绕了一圈,通过使用switch,您可以避免策略模式。除此之外,你不能把你想要调用的所有不同方法添加到你想要的所有类中。但是,您应该使用构造函数注入而不是方法注入来注入
IInterface
。这允许您对所有“请求处理程序”具有相同的方法签名。我喜欢这种方法。不幸的是,我们还没有使用C#7.0