C# 将生成SelectList的两个方法重构为一个方法

C# 将生成SelectList的两个方法重构为一个方法,c#,reflection,refactoring,selectlist,C#,Reflection,Refactoring,Selectlist,我有以下两种方法,它们从数据库中获取数据并返回一个填充的SelectList对象(包括一个“All”选项值),然后将其传递到视图中。问题是它们几乎完全相同,只是它们都访问不同的存储库对象,并且具有不同的ID名称(StatusId和TeamId)。我认为有机会将它们重构为一个方法,该方法接受存储库作为参数,并以某种方式确定ID名称应该是什么,也许可以使用反射或某种lambda表达式,但我不知道如何实现这一点 private SelectList GetStatusSelectList(int se

我有以下两种方法,它们从数据库中获取数据并返回一个填充的SelectList对象(包括一个“All”选项值),然后将其传递到视图中。问题是它们几乎完全相同,只是它们都访问不同的存储库对象,并且具有不同的ID名称(StatusId和TeamId)。我认为有机会将它们重构为一个方法,该方法接受存储库作为参数,并以某种方式确定ID名称应该是什么,也许可以使用反射或某种lambda表达式,但我不知道如何实现这一点

private SelectList GetStatusSelectList(int selectedStatusId)
{
  List<MemberStatus> statusList = _memberStatusRepository.All().ToList();
  statusList.Insert(0, new MemberStatus {StatusId = 0, Name = "All"});
  var statusSelectList = new SelectList(statusList, "StatusId", "Name", selectedStatusId);
  return statusSelectList;
}

private SelectList GetTeamSelectList(int selectedTeamId)
{
  List<MemberTeam> teamList = _memberTeamRepository.All().ToList();
  teamList.Insert(0, new MemberTeam { TeamId = 0, Name = "All" });
  var teamSelectList = new SelectList(teamList, "TeamId", "Name", selectedTeamId);
  return teamSelectList;
}
private SelectList GetStatusSelectList(int-selectedStatusId)
{
列表状态列表=_memberStatusRepository.All().ToList();
插入(0,新成员状态{StatusId=0,Name=“All”});
var statusSelectList=新的SelectList(statusList,“StatusId”,“Name”,selectedStatusId);
返回状态选择列表;
}
私有SelectList GetTeamSelectList(int-selectedTeamId)
{
List teamList=_memberTeamRepository.All().ToList();
插入(0,新成员团队{TeamId=0,Name=“All”});
var teamSelectList=新的SelectList(teamList,“TeamId”,“Name”,selectedTeamId);
返回teamSelectList;
}

有人能帮我找出如何将它们重构成一个单一的方法吗?

好吧,这是我能想到的最通用的方法,但它需要你的
成员状态
成员团队
实现
IIdentifiable
,我不知道这是否适用于你的情况。如果是这样,这将是一条道路

private SelectList GetList<T>(IRepository repository, int id, string name)
    where T : IIdentifiable, new()
{
    List<IIdentifiable> list = repository.All().ToList();
    list.Insert(0, new T() { Name = name, Id = id });
    var statusSelectList = new SelectList(list, "Id", "Name", id);
}

据我所见,将其重构为单一方法的主要障碍是
newmemberstatus
newmemberteam
调用,以及确定要使用的正确存储库

要想出一个优雅的解决方案,您需要配置更多的基础设施——基本上,您需要根据类型解析正确的存储库,并且您需要某种工厂构建对象实例

以下内容将代码重构为一个方法,但(在我看来)并不比现有的单独方法好:

private SelectList GetSelectList<T>(int selectedId, Func<List<T>> repoAllFunc, Func<T> typeNewFunc, string idName)
{
    List<T> list = repoAllFunc();
    list.Insert(0, typeNewFunc());
    var selectList = new SelectList(list, idName, "Name", selectedId);
    return selectList;
}
private SelectList GetSelectList(int-selectedId,Func-repoAllFunc,Func-typeNewFunc,string-idName)
{
List=repoAllFunc();
Insert(0,typeNewFunc());
var selectList=新的selectList(list,idName,“Name”,selectedId);
返回选择列表;
}
你可以这样称呼它:

var memberStatusSelectList = 
    GetSelectList<MemberStatus>(
        id, 
        () => _memberStatusRepository.All().ToList(),
        () => new MemberStatus {StatusId = 0, Name = "All"});
var memberStatusSelectList=
GetSelectList(
身份证件
()=>\u memberStatusRepository.All().ToList(),
()=>newmemberstatus{StatusId=0,Name=“All”});

如果
IRepository
添加了一些“功能”,您将得到一些更清晰的代码

使用处理前两行的
singleRecordswithalRecord()
方法代替
All()
。然后让存储库定义自己的
DataValueField
DataTextField

private SelectList GetSelectList(IRepository repo, int selectedId)
{
   var selectListAll = repo.SingleRecordsWithAllRecord().ToList();

   return new SelectList(selectListAll, 
                         repo.DataValueField, 
                         repo.DataTextField, 
                         selectedId);
}

您可以尝试以下方法:

private SelectList GetStatusSelectList(int selectedStatusId)
{
    return GetGenericSelectList<MemberStatus>(selectedStatusId, _memberStatusRepository.All().ToList(), "StatusId");
}

private SelectList GetTeamSelectList(int selectedTeamId)
{
    return GetGenericSelectList<MemberTeam>(selectedTeamId, _memberTeamRepository.All().ToList(), "TeamId");
}

private SelectList GetGenericSelectList<T>(int selectedTeamId, List<T> list, string idFieldName) where T : new()
{
    var firstItem = new T();
    (firstItem as dynamic).Name = "All";
    var l = new List<T>(list);
    l.Insert(0, firstItem);
    return new SelectList(l, idFieldName, "Name", selectedTeamId);
}
using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication3
{

    public class MemberStatus : IDefault<MemberStatus>
    {
        public int StatusId { get; set; }
        public string Name { get; set; }

        public MemberStatus Default
        {
            get { return new MemberStatus() { StatusId = 0, Name = "All" }; }
        }

        public string IdName
        {
            get { return "StatusId"; }
        }
    }

    public class MemberTeam : IDefault<MemberTeam>
    {
        public int TeamId { get; set; }
        public string Name { get; set; }

        public MemberTeam Default
        {
            get { return new MemberTeam() { TeamId = 0, Name = "All" }; }
        }

        public string IdName
        {
            get { return "TeamId"; }
        }
    }

    public interface IDefault<T>
    {
        T Default { get; }
        string IdName { get; }
    }

    public interface IRepository<T>
    {
        IEnumerable<T> All();
    }

    public class MemberStatusRepository : IRepository<MemberStatus>
    {
        public IEnumerable<MemberStatus> All()
        {
            return new[] { 
                new MemberStatus(),
                new MemberStatus()
            };
        }
    }
    public class MemberTeamRepository : IRepository<MemberTeam>
    {
        public IEnumerable<MemberTeam> All()
        {
            return new[] { 
                new MemberTeam(),
                new MemberTeam()
            };
        }
    }

    public class DataAccessLayer
    {
        IRepository<MemberStatus> _memberStatusRepository;
        IRepository<MemberTeam> _memberTeamRepository;
        public DataAccessLayer()
        {
            _memberStatusRepository = new MemberStatusRepository();
            _memberTeamRepository = new MemberTeamRepository();
        }


        public SelectList<TResult> GetTeamSelectList<TRepository, TResult>(TRepository repo, int selectedTeamId)
            where TRepository : IRepository<TResult>
            where TResult : IDefault<TResult>, new()
        {
            List<TResult> teamList = repo.All().ToList();
            var dummyobj = new TResult();
            teamList.Insert(0, dummyobj.Default);
            var teamSelectList = new SelectList<TResult>(teamList, dummyobj.IdName, "Name", selectedTeamId);
            return teamSelectList;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var dal = new DataAccessLayer();
            SelectList<MemberStatus> results = dal.GetTeamSelectList<IRepository<MemberStatus>, MemberStatus>(new MemberStatusRepository(), 5);
            Console.WriteLine();
            Console.Read();
        }
    }

    public class SelectList<TResult>
    {
        public SelectList(List<TResult> teamList, string p, string p_2, int selectedTeamId)
        {

        }
    }

}
private SelectList GetStatusSelectList(int-selectedStatusId)
{
返回GetGenericSelectList(selectedStatusId,_memberStatusRepository.All().ToList(),“StatusId”);
}
私有SelectList GetTeamSelectList(int-selectedTeamId)
{
返回GetGenericSelectList(selectedTeamId,_memberTeamRepository.All().ToList(),“TeamId”);
}
private SelectList GetGenericSelectList(int-selectedTeamId,List-List,string-idFieldName),其中T:new()
{
var firstItem=new T();
(第一项为动态项)。Name=“全部”;
var l=新列表(列表);
l、 插入(0,第一项);
返回新的SelectList(l,idFieldName,“Name”,selectedTeamId);
}

此解决方案并不理想,并且依赖于某些约定(例如,您的所有项目都应具有
名称
属性)。然而,这似乎是一个不错的开始。可以通过使用表达式而不是属性名来进一步改进,这将允许通过编译时检查来更改属性名。

您可以对接口发疯,并执行以下操作:

private SelectList GetStatusSelectList(int selectedStatusId)
{
    return GetGenericSelectList<MemberStatus>(selectedStatusId, _memberStatusRepository.All().ToList(), "StatusId");
}

private SelectList GetTeamSelectList(int selectedTeamId)
{
    return GetGenericSelectList<MemberTeam>(selectedTeamId, _memberTeamRepository.All().ToList(), "TeamId");
}

private SelectList GetGenericSelectList<T>(int selectedTeamId, List<T> list, string idFieldName) where T : new()
{
    var firstItem = new T();
    (firstItem as dynamic).Name = "All";
    var l = new List<T>(list);
    l.Insert(0, firstItem);
    return new SelectList(l, idFieldName, "Name", selectedTeamId);
}
using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApplication3
{

    public class MemberStatus : IDefault<MemberStatus>
    {
        public int StatusId { get; set; }
        public string Name { get; set; }

        public MemberStatus Default
        {
            get { return new MemberStatus() { StatusId = 0, Name = "All" }; }
        }

        public string IdName
        {
            get { return "StatusId"; }
        }
    }

    public class MemberTeam : IDefault<MemberTeam>
    {
        public int TeamId { get; set; }
        public string Name { get; set; }

        public MemberTeam Default
        {
            get { return new MemberTeam() { TeamId = 0, Name = "All" }; }
        }

        public string IdName
        {
            get { return "TeamId"; }
        }
    }

    public interface IDefault<T>
    {
        T Default { get; }
        string IdName { get; }
    }

    public interface IRepository<T>
    {
        IEnumerable<T> All();
    }

    public class MemberStatusRepository : IRepository<MemberStatus>
    {
        public IEnumerable<MemberStatus> All()
        {
            return new[] { 
                new MemberStatus(),
                new MemberStatus()
            };
        }
    }
    public class MemberTeamRepository : IRepository<MemberTeam>
    {
        public IEnumerable<MemberTeam> All()
        {
            return new[] { 
                new MemberTeam(),
                new MemberTeam()
            };
        }
    }

    public class DataAccessLayer
    {
        IRepository<MemberStatus> _memberStatusRepository;
        IRepository<MemberTeam> _memberTeamRepository;
        public DataAccessLayer()
        {
            _memberStatusRepository = new MemberStatusRepository();
            _memberTeamRepository = new MemberTeamRepository();
        }


        public SelectList<TResult> GetTeamSelectList<TRepository, TResult>(TRepository repo, int selectedTeamId)
            where TRepository : IRepository<TResult>
            where TResult : IDefault<TResult>, new()
        {
            List<TResult> teamList = repo.All().ToList();
            var dummyobj = new TResult();
            teamList.Insert(0, dummyobj.Default);
            var teamSelectList = new SelectList<TResult>(teamList, dummyobj.IdName, "Name", selectedTeamId);
            return teamSelectList;
        }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var dal = new DataAccessLayer();
            SelectList<MemberStatus> results = dal.GetTeamSelectList<IRepository<MemberStatus>, MemberStatus>(new MemberStatusRepository(), 5);
            Console.WriteLine();
            Console.Read();
        }
    }

    public class SelectList<TResult>
    {
        public SelectList(List<TResult> teamList, string p, string p_2, int selectedTeamId)
        {

        }
    }

}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
命名空间控制台应用程序3
{
公共类成员状态:IDefault
{
public int StatusId{get;set;}
公共字符串名称{get;set;}
公共成员状态默认值
{
获取{return new MemberStatus(){StatusId=0,Name=“All”};}
}
公共字符串IdName
{
获取{return“StatusId”;}
}
}
公共类成员组:IDefault
{
public int TeamId{get;set;}
公共字符串名称{get;set;}
公共成员团队默认值
{
获取{return new MemberTeam(){TeamId=0,Name=“All”};}
}
公共字符串IdName
{
获取{return“TeamId”;}
}
}
公共接口故障
{
T默认值{get;}
字符串IdName{get;}
}
公共接口假定
{
i可数全部();
}
公共类MemberStatusRepository:IRepository
{
公共IEnumerable All()
{
返回新的[]{
新成员状态(),
新成员状态()
};
}
}
公共类MemberTeamRepository:IRepository
{
公共IEnumerable All()
{
返回新的[]{
新成员团队(),
新成员团队()
};
}
}
公共类数据访问层
{
IRepository\u memberStatusRepository;
IRepository\u成员团队存储库;
公共数据访问层()
{
_memberStatusRepository=新建memberStatusRepository();
_memberTeamRepository=新建memberTeamRepository();
}
public SelectList GetTeamSelectList(存款回购、整数选择)