Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/320.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#_Solid Principles - Fatal编程技术网

C# 控制器动作法中的开闭原理

C# 控制器动作法中的开闭原理,c#,solid-principles,C#,Solid Principles,我有一个ASP.NETMVC项目,我需要遵循开放-封闭原则 该项目将.csv文件从数据库转换为模型,但将来我们可能还必须将excel文件从数据库转换为相同的模型 现在,控制器中有以下代码: public ActionResult Index(HttpPostedFileBase file) { // Verify that the user selected a file if (file != null && file.ContentLength

我有一个ASP.NETMVC项目,我需要遵循开放-封闭原则

该项目将
.csv
文件从数据库转换为模型,但将来我们可能还必须将excel文件从数据库转换为相同的模型

现在,控制器中有以下代码:

public ActionResult Index(HttpPostedFileBase file)
{
        // Verify that the user selected a file
        if (file != null && file.ContentLength > 0)
        {
            var path = FileHelper.GetFilePath(file);                
            string filePath = path.Item1;

            if (!string.IsNullOrEmpty(filePath))
            {                    
                if (path.Item2 == "." + Enums.FileType.csv.ToString())
                {
                    List<Company> companiesList = Convertor.ConvertCsvToCompanyModel(filePath);

                    if (companiesList != null && companiesList.Count() > 0)
                    {
                        try
                        {
                            foreach (var company in companiesList)
                            {
                                companyRepository.SaveCompanyItem(company);
                            }
                        }
                        catch(Exception ex)
                        {
                            obj.Handle("Something went wrong at save" + ex.Message);
                        }
                    }

                    TempData["Message"] = "The file import was sucessfull!";
                }
            }
        }

        TempData["ErrorMessage"] = "Please select file";

        // redirect back to the index action to show the form once again           
        return RedirectToAction("Index");
}
公共操作结果索引(HttpPostedFileBase文件) { //验证用户是否选择了一个文件 如果(file!=null&&file.ContentLength>0) { var path=FileHelper.GetFilePath(文件); 字符串filePath=path.Item1; 如果(!string.IsNullOrEmpty(文件路径)) { if(path.Item2==““+Enums.FileType.csv.ToString()) { 列表公司列表=Convertor.ConvertCsvToCompanyModel(文件路径); if(companiesList!=null&&companiesList.Count()>0) { 尝试 { foreach(公司列表中的var公司) { companyRepository.SaveCompanyItem(公司); } } 捕获(例外情况除外) { obj.Handle(“保存时出错”+ex.Message); } } TempData[“Message”]=“文件导入成功!”; } } } TempData[“ErrorMessage”]=“请选择文件”; //重定向回索引操作以再次显示表单 返回操作(“索引”); }
你能给我一些提示如何做到这一点吗?我认为,如果我们想将Excel转换为文件,最好不要在这个操作方法中使用更多的if-s。谢谢

相信我,控制器或甚至
索引
操作与您在
文件
上执行的任何操作无关。他们所关心的只是用户上传的文件中的数据

我会将所有
文件
内容移动到单独的类中,比如说
文件服务
,然后在控制器内使用此服务。由于需要同时支持CSV(当前)、Excel(未来)或两者(您没有提到这一点),我们可以考虑策略模式和工厂方法模式

public interface IFileProcessor {
 // add proper constraint for T
 List < T > GetRecords < T > (...);
}

public class CsvFileProcessor: IFileProcessor {
 List < T > GetRecords < T > (...) {}
}

public class ExcelFileProcessor: IFileProcessor {
 List < T > GetRecords < T > (...) {}
}

public class FileService {
 public List < T > ReadFile < T > (HttpPostedFileBase file) {
  // do whatever with `file` here
  IFileProcessor fileProcessor = GetFileProcessor( < fileExt > );
  return fileProcessor.GetRecords < T > (...);
 }

 // This is not exact implementation of factory but it serves the same purpose as factory method.
 private static IFileProcessor GetFileProcessor(string fileExt) {
  if ( < csv > ) {
   return ServiceLocator.Current.GetInstance < IFileProcessor > ("csv");
  } 
  else if ( < excel > ) {
   return ServiceLocator.Current.GetInstance < IFileProcessor > ("excel");
  }
 }
}
公共接口IFileProcessor{ //为T添加适当的约束 列表获取记录(…); } 公共类CsvFileProcessor:IFileProcessor{ 列表GetRecords(…){} } 公共类ExcelFileProcessor:IFileProcessor{ 列表GetRecords(…){} } 公共类文件服务{ 公共列表读取文件(HttpPostedFileBase文件){ //在这里用'file'做任何事 IFileProcessor fileProcessor=GetFileProcessor(); 返回fileProcessor.GetRecords(…); } //这不是工厂的精确实现,但它与工厂方法的用途相同。 专用静态IFileProcessor GetFileProcessor(字符串fileExt){ 如果(){ 返回ServiceLocator.Current.GetInstance(“csv”); } 如果(){ 返回ServiceLocator.Current.GetInstance(“excel”); } } } 提示:
CsvFileProcessor
ExcelFileProcessor
可以轻松使用和libs。您只需指定模型/实体类型,libs将返回反序列化为该类型的记录列表


现在将此
文件服务
注入控制器。

相信我,控制器甚至
索引
操作与您在
文件
上执行的任何操作无关。他们所关心的只是用户上传的文件中的数据

我会将所有
文件
内容移动到单独的类中,比如说
文件服务
,然后在控制器内使用此服务。由于需要同时支持CSV(当前)、Excel(未来)或两者(您没有提到这一点),我们可以考虑策略模式和工厂方法模式

public interface IFileProcessor {
 // add proper constraint for T
 List < T > GetRecords < T > (...);
}

public class CsvFileProcessor: IFileProcessor {
 List < T > GetRecords < T > (...) {}
}

public class ExcelFileProcessor: IFileProcessor {
 List < T > GetRecords < T > (...) {}
}

public class FileService {
 public List < T > ReadFile < T > (HttpPostedFileBase file) {
  // do whatever with `file` here
  IFileProcessor fileProcessor = GetFileProcessor( < fileExt > );
  return fileProcessor.GetRecords < T > (...);
 }

 // This is not exact implementation of factory but it serves the same purpose as factory method.
 private static IFileProcessor GetFileProcessor(string fileExt) {
  if ( < csv > ) {
   return ServiceLocator.Current.GetInstance < IFileProcessor > ("csv");
  } 
  else if ( < excel > ) {
   return ServiceLocator.Current.GetInstance < IFileProcessor > ("excel");
  }
 }
}
公共接口IFileProcessor{ //为T添加适当的约束 列表获取记录(…); } 公共类CsvFileProcessor:IFileProcessor{ 列表GetRecords(…){} } 公共类ExcelFileProcessor:IFileProcessor{ 列表GetRecords(…){} } 公共类文件服务{ 公共列表读取文件(HttpPostedFileBase文件){ //在这里用'file'做任何事 IFileProcessor fileProcessor=GetFileProcessor(); 返回fileProcessor.GetRecords(…); } //这不是工厂的精确实现,但它与工厂方法的用途相同。 专用静态IFileProcessor GetFileProcessor(字符串fileExt){ 如果(){ 返回ServiceLocator.Current.GetInstance(“csv”); } 如果(){ 返回ServiceLocator.Current.GetInstance(“excel”); } } } 提示:
CsvFileProcessor
ExcelFileProcessor
可以轻松使用和libs。您只需指定模型/实体类型,libs将返回反序列化为该类型的记录列表


现在,将这个
文件服务
注入控制器。

这个逻辑应该在服务内部。如果你想谈论OCP,我宁愿看一看名为
转换器
的类,它看起来会做很多不相关的事情,更不用说它是静态访问的。您发布的方法的问题更像是SRP冲突:1。验证输入,并据此决定行动和结果。执行操作以处理输入,3。坚持结果。还有2。三,。应该位于上面评论中提到的另一层。看起来像是一个Stra