2010-07-19 3 views
3

내 asp.net mvc 웹 응용 프로그램에서 리포지토리 패턴을 구현했습니다 ...하지만이 좋은 저장소 패턴인지 알고 싶습니다 또는 더 그것을 향상시킬 수 있습니다 ...asp.net mvc 좋은 저장소 패턴

... 어떤 제안을 내가 여기 IRepository을 구현하지 않았나요

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 

namespace TaxiMVC.BusinessObjects 
{ 
    public class ClientBO 
    { 
     public int ClientId { get; set; } 
     public string ClientName { get; set; } 
     public string ClientMobNo { get; set; } 
     public string ClientAddress { get; set; } 
     public DateTime CreatedDate { get; set; } 
     public byte IsDeleted { get; set; } 
     public int CreatedBy { get; set; } 
    } 
} 

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Web; 
using TaxiMVC.BusinessObjects; 

namespace TaxiMVC.Models 
{ 
    public class ClientRepository 
    { 
     private TaxiDataContext taxidb = new TaxiDataContext(); 
     Client cli = new Client(); 

     //Get all Clients 
     public IQueryable<ClientBO> FindAllClients(int userId) 
     { 
      var client = from c in taxidb.Clients 
         where c.CreatedBy == userId && c.IsDeleted == 0 
         select new ClientBO() 
         { 
          ClientId = c.ClientId, 
          ClientName= c.ClientName, 
          ClientMobNo= Convert.ToString(c.ClientMobNo), 
          ClientAddress= c.ClientAddress 
         }; 
      return client; 
     } 

     //Get Client By Id 
     public ClientBO FindClientById(int userId,int clientId) 
     { 
      return (from c in taxidb.Clients 
        where c.CreatedBy == userId && c.ClientId == clientId && c.IsDeleted == 0 
         select new ClientBO() 
         { 
          ClientId = c.ClientId, 
          ClientName= c.ClientName, 
          ClientMobNo= Convert.ToString(c.ClientMobNo), 
          ClientAddress= c.ClientAddress 
         }).FirstOrDefault(); 
     } 

     //Insert a new client 
     public bool ClientInsert(ClientBO clientBO) 
     { 
      cli.ClientName = clientBO.ClientName; 
      cli.ClientMobNo = Convert.ToInt64(clientBO.ClientMobNo); 
      cli.ClientAddress = clientBO.ClientAddress; 
      cli.CreatedDate = clientBO.CreatedDate; 
      cli.IsDeleted = clientBO.IsDeleted; 
      cli.CreatedBy = clientBO.CreatedBy; 

      if (!taxidb.Clients.Where(c => c.ClientMobNo == cli.ClientMobNo).Any()) 
      { 
       taxidb.Clients.InsertOnSubmit(cli); 
       taxidb.SubmitChanges(); 
       return true; 
      } 
      else 
       return false; 
     } 

     //Client Update 
     public ClientBO updateClient(ClientBO clientBO) 
     { 
      var table = taxidb.GetTable<Client>(); 
      var cli = table.SingleOrDefault(c => c.ClientId == clientBO.ClientId && c.CreatedBy==clientBO.CreatedBy); 
      cli.ClientName = clientBO.ClientName; 
      cli.ClientMobNo = Convert.ToInt64(clientBO.ClientMobNo); 
      cli.ClientAddress = clientBO.ClientAddress; 
      taxidb.SubmitChanges(); 
      return clientBO; 
     } 

     //Delete Clients 
     public bool deleteClients(string Ids, int userId) 
     { 
      var idsToDelete = Ids.Split(',').Select(c => Convert.ToInt32(c)); 
      var clientsToDelete = taxidb.Clients.Where(c => idsToDelete.Contains(c.ClientId)); 
      foreach (var client in clientsToDelete) 
      { 
       client.IsDeleted = Convert.ToByte(1); 
      } 
      taxidb.SubmitChanges(); 
      return true; 
     } 
    } 
} 

내 ClientBo.cs 은 ... 나는 그것을 구현했습니다해야 또는 내 저장소는 여전히 개선 될 수 있습니다. ...

+0

엄밀히 말하면, "저장소"패턴이 아닙니다. 더 자세히 읽을 수 있습니다 : http://fabiomaulo.blogspot.com/2009/09/repository-or-dao-repository.html – griZZZly8

답변

15

흠, 이것을 향상시키기 위해 분명히 할 일이 몇 가지 있습니다.

첫 번째 : 구현할 리포지토리의 인터페이스를 정의합니다. 이렇게하면 종속성을보다 강력하게 제어 할 수 있으며 Inversion Of Control/Dependency Injection (IOC/DI) 프레임 워크와 결합하면 대폭 개선됩니다. IOC/DI 프레임 워크에는 StructureMap 또는 NInjet이 포함됩니다. Scott Hanselman의 this을 읽으십시오. 꽤 포괄적 인 목록입니다.

사용자 인터페이스 보일 수 있습니다 같은 :

public interface IClientRepository 
{ 
    IQueryable<ClientBO> FindAllClients(int userId); 
    ClientBO FindClientById(int userId, int clientId); 
    ClientInsert(ClientBO clientBO); 
    ClientBO updateClient(ClientBO clientBO); 
    bool deleteClients(string Ids, int userId); 
} 

둘째 :이 저장소 안에 영속 객체 (Client) 변환하여 비즈니스 오브젝트 (ClientBO)를하지 않습니다. 즉, BO에 변경 사항을 적용하면 전체 저장소를 변경해야합니다.

많은 양의 좌우 대입 코드가 있음을 확인했습니다.

cli.ClientName = clientBO.ClientName; 

난 심각 AutoMapper의 사용을 조사 할 것입니다. 그것은이 "원숭이 코드"를 훨씬 더 쉽게 만듭니다.

편집 : Here is a blog post AutoMapper를 사용하여 왼쪽/오른쪽 할당 코드를 제거하는 방법을 설명합니다.

세 번째 : 귀하의 명명 체계는 모든 매장에서 제공됩니다. 우리는 FindAllClients(), ClientInsert(), updateClient()을 모두 가지고 있습니다. 매우 가난한 이름입니다. 당신의 저장소를 위해, DB 측에서 일어날 일들에 대해 당신의 방법을 모델링 해보십시오. Add 또는 Insert, Delete, FindAll 또는 GetAll, Find 또는 GetAll, SaveChanges, 메소드 이름을 시도해보십시오.

ClientRepository에있는대로 메서드 이름에 형식을 덧붙이거나 붙이지 마십시오. Client을 추가하거나 가져올 것임을 암시합니다.

넷째 : 사용자의 LINQ 구문을 혼합합니다. 어떤 곳에서는 선언적 쿼리 구문을 사용하고 다른 곳에서는 메서드 구문을 사용합니다. 1을 골라 사방에 사용하십시오. 다섯 번째

:이 줄은 저를 걱정 :

if (!taxidb.Clients.Where(c => c.ClientMobNo == cli.ClientMobNo).Any()) 

이 의심스럽게 나에게 비즈니스 로직처럼 보인다. 저장소에 있어야하는 것은 아닙니다. DB에 열을 UNIQUE으로 선언하거나 해당 논리를 다른 유효성 검사 계층으로 이동하십시오.

이들은 나에게 뛰어든 주요한 것들이었다. 이 두 가지는 개인적인 취향이지만, 이것이 도움이되기를 바랍니다.

+1

@Alaistar +1 좋은 답변 ..하지만 두 번째 포인트를 얻을 수 없습니다. .. 두 번째 포인트를 오토마터로 업데이트 할 수 있습니까? –

+0

프로세스를 설명하는 좋은 블로그 게시물 링크가 업데이트됩니다. –

+0

좋은 답변 -하지만 LINQ 구문에 대한 귀하의 의견에 경의를 표합니다. LINQ 문을 정의하는 데있어 실용적인 접근법을 취하는 것이 가장 이해하기 쉬운 방식으로 작성해야합니다. –

1

왜 당신 이드의 배열 문자열을 사용 않았다

public bool deleteClients(string Ids, int userId) 

나는 당신이 int[] 또는 List<int> 사용한다고 생각합니다.

또한 FindAllClients에는 List가 있지만 IQueryable은 쓰지 않습니다.

물론 IClientRepository 인터페이스를 작성해야합니다. 솔리드 원리에 따라 올바른 접근 방식이기 때문입니다. 당신이 인터페이스를 쓸 것이다 경우

, 당신은 더 유연이 인터페이스와 저장소를 사용하는 다른 클래스, 같은 것을 쓸 수 있습니다 :

public class ClientService : IClientService 
{ 
    IClientRepository m_clientRepository; 

    public ClientService(IClientRepository rep) 
    { 
     m_clientRepository = rep; 
    } 
} 

을 그리고 당신은 Mock-이 코드를 테스트 할 수 있습니다 IClientRepository Moq와 같은 것을 사용합니다. 물론 IClientRepository (예 : XmlClientRepository)이라고 쓰면 리파지토리를 사용하는 클래스의 초기화 만 변경됩니다.

ASP.NET MVC를 사용하는 경우 컨트롤러에 IClientRepository을 사용할 수 있으며 더 테스트 할 수 있습니다.

좀 더 유연한 해결책을 위해 IoC 컨테이너 패턴 (NInject, Unity)을 사용할 수 있습니다.

이 답변으로 도움이되기를 바랍니다.