C#重构代码以使泛型可重用

C#重构代码以使泛型可重用,c#,.net,generics,C#,.net,Generics,这是一个非常复杂的问题,但我对使用泛型还不熟悉,我希望能够熟练地使用泛型,并将我的C#/.NET技能提升到一个新的水平。我使用多个下拉菜单创建了一个数据过滤器。在我将下面的方法分解为更小的封装、单一责任方法之前,我希望能得到一些帮助 我的目标是在应用程序的许多部分重复使用这个过滤器。为了做到这一点,我必须将“filter”方法添加到通用的基本EntityController和EntityRespository类中。显然,我将不得不使用泛型来完成这项任务。在看了下面这个(长得可笑)的方法之后,有人

这是一个非常复杂的问题,但我对使用泛型还不熟悉,我希望能够熟练地使用泛型,并将我的C#/.NET技能提升到一个新的水平。我使用多个下拉菜单创建了一个数据过滤器。在我将下面的方法分解为更小的封装、单一责任方法之前,我希望能得到一些帮助

我的目标是在应用程序的许多部分重复使用这个过滤器。为了做到这一点,我必须将“filter”方法添加到通用的基本EntityController和EntityRespository类中。显然,我将不得不使用泛型来完成这项任务。在看了下面这个(长得可笑)的方法之后,有人能给我一些建议吗

[HttpPost(“FilteredResults”)]
[ProductsResponseType(typeof(PaginatedList),StatusCodes.Status200OK)]
[产品响应类型(StatusCodes.Status400BadRequest)]
[产品响应类型(StatusCodes.Status403禁止)]
[产品响应类型(StatusCodes.Status404NotFound)]
[产品响应类型(StatusCodes.Status422不可处理实体)]
[ProductsDefaultResponseType]
[产生(“应用程序/json”)]
公共异步任务GetFilteredBusiness Process([FromBody]列表filterCriteriaList=null)
{
尝试
{
List listOfCommonItems=新列表();
PaginatedList PaginatedListofCommonims=新的PaginatedList();
var orgIdGuid=filterCriteriaList[0]?.OrganizationId;
如果(filterCriteriaList!=null)
{
var results=repository.Find(null,a=>a.OrganizationId==orgIdGuid);
foreach(filterCriteriaList中的FieldFilterCriteria过滤器)
{
foreach(过滤器中的字符串值?.FilterValues)
{
开关(过滤器字段)
{
案例“部门”:
var dList=results?.Items.Where(x=>x.OrganizationUnitId==Guid.Parse(value)).ToList();
常用项列表。添加范围(dList);
打破
案例“状态”:
var sList=results?.Items.Where(x=>x.Status==value.ToList();
常用项列表。添加范围(sList);
打破
案例“优先权”:
var pList=results?.Items.Where(x=>x.Priority==value).ToList();
常用项列表。添加范围(pList);
打破
案例“所有人”:
var oList=results?.Items.Where(x=>x.OwnerName==value).ToList();
常用项列表。添加范围(oList);
打破
}
}
}
如果(filterCriteriaList.Count==1)
{
paginatedListOfCommonItems.Items=常用项列表;
}
如果(filterCriteriaList.Count>1)
{
listOfCommonItems=listOfCommonItems.GroupBy(x=>x).Where(x=>x.Count()>1).选择(x=>x.Key).ToList();
paginatedListOfCommonItems.Items=常用项列表;
}
var businessProcessCard=processCatalogManager.GetBusinessProcessCard(PaginatedListofCommonims);
返回Ok(businessProcessCard);
}
其他的
{
返回Ok();
}
}
捕获(例外情况除外)
{
返回例如GetActionResult();
}
}

我认为更大的问题,而不是泛型,应该是你担心让你的控制器“瘦”起来。您在操作中拥有的所有这些逻辑都应该在作为依赖项注入的服务中。如果您在尝试实现泛型之前重构到更小、更可测试的方法,您将省去很多麻烦。修复3个小方法要比修复1个在3个方面失败的大方法容易得多。对不起,伙计们,我认为我在解释方面做得更好。我已经有了这个控制器类的服务。我将使用Resharper的重构工具将它们分解成更小的方法。我们(我认为大多数人)在控制器中没有任何逻辑。这只是我第一次获得一个有效的例子。它将被分解成3个较小的方法,然而,我希望你能看到它的整体,而不是我发布多个封装的、单一责任的方法供你筛选。我希望这能澄清我的意图。有什么建议吗?
        [HttpPost("FilteredResults")]
        [ProducesResponseType(typeof(PaginatedList<ProcessCard>), StatusCodes.Status200OK)]
        [ProducesResponseType(StatusCodes.Status400BadRequest)]
        [ProducesResponseType(StatusCodes.Status403Forbidden)]
        [ProducesResponseType(StatusCodes.Status404NotFound)]
        [ProducesResponseType(StatusCodes.Status422UnprocessableEntity)]
        [ProducesDefaultResponseType]
        [Produces("application/json")]
        public async Task<IActionResult> GetFilteredBusinessProcesses([FromBody] List<FieldFilterCriteria> filterCriteriaList = null)
        {
            try
            {
                List<BusinessProcess> listOfCommonItems = new List<BusinessProcess>();
                PaginatedList<BusinessProcess> paginatedListOfCommonItems = new PaginatedList<BusinessProcess>();
                var orgIdGuid = filterCriteriaList[0]?.OrganizationId;

                if (filterCriteriaList != null)
                {
                    var results = repository.Find(null, a => a.OrganizationId == orgIdGuid);

                    foreach (FieldFilterCriteria filter in filterCriteriaList)
                    {
                        foreach (string value in filter?.FilterValues)
                        {
                            switch (filter.Field)
                            {
                                case "Department":
                                    var dList = results?.Items.Where(x => x.OrganizationUnitId == Guid.Parse(value)).ToList();
                                    listOfCommonItems.AddRange(dList);
                                    break;
                                case "Status":
                                    var sList = results?.Items.Where(x => x.Status == value).ToList();
                                    listOfCommonItems.AddRange(sList);
                                    break;
                                case "Priority":
                                    var pList = results?.Items.Where(x => x.Priority == value).ToList();
                                    listOfCommonItems.AddRange(pList);
                                    break;
                                case "Owner":
                                    var oList = results?.Items.Where(x => x.OwnerName == value).ToList();
                                    listOfCommonItems.AddRange(oList);
                                    break;
                            }
                        }
                    }

                    if (filterCriteriaList.Count == 1)
                    {
                        paginatedListOfCommonItems.Items = listOfCommonItems;
                    }

                    if (filterCriteriaList.Count > 1)
                    {
                        listOfCommonItems = listOfCommonItems.GroupBy(x => x).Where(x => x.Count() > 1).Select(x => x.Key).ToList();
                        paginatedListOfCommonItems.Items = listOfCommonItems;
                    }

                    var businessProcessCard = processCatalogManager.GetBusinessProcessCard(paginatedListOfCommonItems);

                    return Ok(businessProcessCard);
                }
                else
                {
                    return Ok(); 
                }
            }
            catch (Exception ex)
            {
                return ex.GetActionResult();
            }
        }