我在应用程序中使用Dapper ORM。我已经创建了一个带有Dapper方法的接口,可以快速浏览一下Dapper的哪些功能正在这个应用程序中使用,并且可以通过实现它轻松地被其他ORM替换。
public interface IDapperRepository
{
IEnumerable<T> GetAll<T>(string query, object cmdParams = null, CommandType cmdType = CommandType.Text) where T : class;
T GetById<T>(string query, object cmdParams = null, CommandType cmdType = CommandType.Text) where T : class;
}
class DapperRepository : IDapperRepository
{
public IEnumerable<T> GetAll<T>(string query, object cmdParams = null, CommandType cmdType = CommandType.Text) where T : class
{
//implementation
}
public T GetById<T>(string query, object cmdParams = null, CommandType cmdType = CommandType.Text) where T : class
{
//implementation
}
}
来自DAL层:
public class UserRep : IUserRep
{
private readonly IDapperRepository _iDapperRepository;
public UserRep()
{
_iDapperRepository = new DapperRepository();
}
public IEnumerable<UserBO> GetAll()
{
return _iDapperRepository.GetAll<UserBO>("select * from users");
}
//Other methods
}
在用户列表页面中,从控制器调用_iUserRep.GetAll()。
从上面的代码中,通过调用_iUserRep.GetAll()或存储库类中的任何其他方法,DapperRepository类被实例化。我的问题是因为我在DapperRepository类中只有实用程序方法,所以最好删除IDapperRepository并使用“静态”方法将DapperRepository修改为“静态”,以便我可以在不实例化的情况下调用方法。我想知道这样做是否会带来任何性能提升。
此外,赞赏任何改进此设计的输入。
答案 0 :(得分:0)
由于这是关于更好的概念的问题,我将介绍我要做的事情。首先尝试限制您的抽象和开销复杂性 - 首先简化,最后自动化。您是否有可能更改存储库实现以使用不同的ORM?如果不这样做,请不要使用这种方法。这是老派的存储库风格,乍一看似乎没问题,但最终会被重估和多余 - 至少在我看来。由于它是ASP.MVC应用程序,您可以尝试使用命令:
public abstract class BaseController : Controller
{
public IDocumentSession DocumentSession { get; set; }
protected override void OnActionExecuting(ActionExecutingContext filterContext)
{
DocumentSession = ...OpenSession(); // initialize and open session
}
protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
if (filterContext.IsChildAction)
{
return;
}
using (DocumentSession)
{
if (filterContext.Exception != null)
{
return;
}
if (DocumentSession != null)
{
DocumentSession.SaveChanges();
}
}
}
public void ExecuteCommand(Command cmd)
{
cmd.DocumentSession = DocumentSession;
cmd.Execute();
}
public TResult ExecuteCommand<TResult>(Command<TResult> cmd)
{
ExecuteCommand((Command)cmd);
return cmd.Result;
}
}
抽象命令定义:
public abstract class Command
{
public IDocumentSession DocumentSession { get; set; }
public abstract void Execute();
}
public abstract class Command<T> : Command
{
public T Result { get; protected set; }
}
示例命令实现:
public class GetUsers : Command<IList<User>>
{
public IList<int> IDs { get; set; }
public override void Execute()
{
return DocumentSession.Query<User>()...;
}
}
用法 - 执行表单控制器操作:
[HttpGet]
public NJsonResult GetUsers(string ids)
{
var result = ExecuteCommand(new GetUsers
{
IDs = ids
});
//...
}
在我看来,这不是一个微不足道的问题。需要相当多的考虑。为了更好地理解它,您可以尝试在空闲时间浏览Ayende的博客:
以及下面的系列(短文,真的很快通过):
http://ayende.com/blog/153889/limit-your-abstractions-analyzing-a-ddd-application
http://ayende.com/blog/153921/limit-your-abstractions-application-eventsndash-what-about-change
http://ayende.com/blog/153953/limit-your-abstractions-application-eventsndash-proposed-solution-1
......从这里开始变得更有趣:
http://ayende.com/blog/154081/limit-your-abstractions-you-only-get-six-to-a-dozen-in-the-entire-app
http://ayende.com/blog/154113/limit-your-abstractions-commands-vs-tasks-did-you-forget-the-workflow
http://ayende.com/blog/154177/limit-your-abstractions-so-what-is-the-whole-big-deal-about
http://ayende.com/blog/154209/limit-your-abstractions-refactoring-toward-reduced-abstractions
http://ayende.com/blog/154241/limit-your-abstractions-the-key-is-in-the-infrastructurehellip
http://ayende.com/blog/154273/limit-your-abstractions-and-how-do-you-handle-testing
我希望它可以让您另外看一下这个主题。