Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/21.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 重构C代码以实现某种工厂设计模式_C#_.net_Design Patterns - Fatal编程技术网

C# 重构C代码以实现某种工厂设计模式

C# 重构C代码以实现某种工厂设计模式,c#,.net,design-patterns,C#,.net,Design Patterns,我有一个Web API应用程序(.NET Core),它是我后端的一部分。我已经将工作单元和存储库模式实现到一个N层1层体系结构中。客户端应用程序和后端通信的方式是通过发送DTO(数据传输对象)。因此,根据存储库方法的请求,我有不同的DTO,显然有不同的结构和组成。这是因为在设计时,我定义了客户端期望的数据类型,如下所示: public EmployeeDto GetEMployeeDto() { public EmployeeDto employee = new EmployeeDto

我有一个Web API应用程序(.NET Core),它是我后端的一部分。我已经将工作单元和存储库模式实现到一个N层1层体系结构中。客户端应用程序和后端通信的方式是通过发送DTO(数据传输对象)。因此,根据存储库方法的请求,我有不同的DTO,显然有不同的结构和组成。这是因为在设计时,我定义了客户端期望的数据类型,如下所示:

public EmployeeDto GetEMployeeDto()
{
    public EmployeeDto employee = new EmployeeDto();
    
    .
    .
    .
    // Code to get data from data base and full fill the fields of the DTO.
    .
    .
    .

    return EmployeeDto;

}
public cladd EmployeeDto()
{
     public int Employee Id {get;set;}
     public string EmployeeName {get;set;}
}
public interface IRepository<T>
{
    IEnumerable<T> GetAll<T>();
    T Get<T>(int id);
}
其中
EmployeeDto
是这样的:

public EmployeeDto GetEMployeeDto()
{
    public EmployeeDto employee = new EmployeeDto();
    
    .
    .
    .
    // Code to get data from data base and full fill the fields of the DTO.
    .
    .
    .

    return EmployeeDto;

}
public cladd EmployeeDto()
{
     public int Employee Id {get;set;}
     public string EmployeeName {get;set;}
}
public interface IRepository<T>
{
    IEnumerable<T> GetAll<T>();
    T Get<T>(int id);
}
我想做的是删除紧耦合的实例化代码(
public EmployeeDto employee=new EmployeeDto();
),并实现某种工厂模式,在这里我只调用工厂对象,将数据类型传递给我想要的(因为我已经知道它)工厂返回我请求的DTO类型和DTO状态(数据)

请记住,我有几种不同结构的DTO,因此它们的填充方式不同,工厂对象可以用不同的方法调用,可以请求不同的DTO

比如:

var employee = FactoryDto.GetDto(EmployeDto);
var employeeHistory = FactoryDto.GetDto(EmployeeHistoryDto);
只需一行就可以将整个“包”数据传输到数据本身和数据

我只需要一个关于哪种设计模式是最好的选择的指南和一个例子,我已经读过关于Creational Design Pattern Factory及其不同风格的文章,但我还不明白这是如何实现的

这是我的方法之一:

public EmployeeDto GetEmployeeDto(string dtoType)
{
    var factoryDto = new FactoryDto();
    var empDto = factoryDto.GetDto(dtoType);

    return (EmployeeDto)empDto;
}


public class FactoryDto
{
    public object GetDto(string dtoType)
    {
        switch(dtoType)
        {
            case "EmployeeDto":
                {
                    return new EmployeeDto();
                }
            case "EmployeeHistoryDto":
                {
                    return new EmployeeHistoryDto();
                }
            default:
                {
                    return new EmployeeHistoryDto();
                }
        }
            
    }

}
但是,我认为这不是一个正确的答案,在返回Dto时强制转换Dto,我不喜欢Factory类中的对象泛型类型。有没有更好的方法来改进这种方法使用任何创造性的设计模式?问候

没有办法(至少对我来说没有办法)将用于处理特定类型的实现与该类型解耦。对于处理
EmployeeDto
类型的存储库来说,直接了解该类型似乎很自然

不确定您的设计从更广泛的角度来看如何,但可能您缺少的是一个通用接口,因此您的客户端没有太多耦合?例如,类似这样的内容:

public EmployeeDto GetEMployeeDto()
{
    public EmployeeDto employee = new EmployeeDto();
    
    .
    .
    .
    // Code to get data from data base and full fill the fields of the DTO.
    .
    .
    .

    return EmployeeDto;

}
public cladd EmployeeDto()
{
     public int Employee Id {get;set;}
     public string EmployeeName {get;set;}
}
public interface IRepository<T>
{
    IEnumerable<T> GetAll<T>();
    T Get<T>(int id);
}
公共接口IRepository
{
IEnumerable GetAll();
T Get(int-id);
}
这意味着,您不会像示例中那样使用
GetEmployeeDto
方法,而是使用常规的
GetDto
方法,甚至
Get
。这让我想到了另一个提示:遵循DDD相关模式,存储库应该返回一个准备好使用的域对象,而不是DTO

这样,您的域层就可以使用存储库并专注于域逻辑,而不是被迫处理转换。正如在评论中提到的,无论如何,配置一个自动映射库来为您实现这一点是很好的。但是,即使使用automapper,所有技术细节都应该隐藏在域层之外。

没有办法(至少对我来说没有办法)将用于处理特定类型的实现与该类型解耦。对于处理
EmployeeDto
类型的存储库来说,直接了解该类型似乎很自然

不确定您的设计从更广泛的角度来看如何,但可能您缺少的是一个通用接口,因此您的客户端没有太多耦合?例如,类似这样的内容:

public EmployeeDto GetEMployeeDto()
{
    public EmployeeDto employee = new EmployeeDto();
    
    .
    .
    .
    // Code to get data from data base and full fill the fields of the DTO.
    .
    .
    .

    return EmployeeDto;

}
public cladd EmployeeDto()
{
     public int Employee Id {get;set;}
     public string EmployeeName {get;set;}
}
public interface IRepository<T>
{
    IEnumerable<T> GetAll<T>();
    T Get<T>(int id);
}
公共接口IRepository
{
IEnumerable GetAll();
T Get(int-id);
}
这意味着,您不会像示例中那样使用
GetEmployeeDto
方法,而是使用常规的
GetDto
方法,甚至
Get
。这让我想到了另一个提示:遵循DDD相关模式,存储库应该返回一个准备好使用的域对象,而不是DTO


这样,您的域层就可以使用存储库并专注于域逻辑,而不是被迫处理转换。正如在评论中提到的,无论如何,配置一个自动映射库来为您实现这一点是很好的。但是,即使使用automapper,所有的技术细节都应该隐藏在域层。

新员工待办事项()有什么问题吗??我个人不会费心,只会使用automapper或类似工具,然后得到一个键入的结果<代码>地图(dto)。您使用单个方法和1或0个泛型参数提出的任何此类解决方案都需要强制转换,并且需要使用if语句或类似语句在内部检查类型。工厂如何知道要为哪个员工获取DTO?Hello@MarkSeemann!根据工厂模式,客户机(实例化类的方法)不应该创建对象,该责任应该委托给其他人(在本例中是工厂),这样创建逻辑就不会向客户机公开(这不重要)工厂将返回请求的对象。您好@TheGeneral!在返回时强制转换Dto可能是一种解决方案,类似于首先将结果分配到通用对象类型,然后将对象强制转换为所请求类型的Dto:return(EmployeeDto)Object;理解这一点,谢谢你的贡献。
new EmployeeDto()
有什么问题吗?我个人不想麻烦,只要使用auto mapper或类似工具,就可以得到一个键入的结果<代码>地图(dto)。您使用单个方法和1或0个泛型参数提出的任何此类解决方案都需要强制转换,并且需要使用if语句或类似语句在内部检查类型。工厂如何知道要为哪个员工获取DTO?Hello@MarkSeemann!根据工厂模式,客户机(实例化类的方法)不应该创建对象,该责任应该委托给其他人(在本例中是工厂),这样创建