Соглашение об именах проектов - PullRequest
1 голос
/ 21 февраля 2011

Я создаю приложение ASP.NET MVC 3 с использованием Entity Framework 4. Я использую шаблон репозитория / службы и искал обратную связь.

В настоящее время у меня есть следующее:

Приложение MVC (GTG.dll)

  • GTG
  • GTG.Controllers
  • GTG.ViewModels

Бизнес POCO (GTG.Business.dll)

  • Содержит все бизнес-объекты (Клиент, Заказ, Счет и т. Д.)

Модель EF / Хранилища (GTG.Data.dll)

  • GTG.Business (GTG.Context.tt) Я использовал шаблоны генератора сущностей POCO.
  • GTG.Data.Repositories

Сервисный уровень (GTG.Data.Services.dll)

  • GTG.Data.Services - Содержит все объекты службы, по одному на совокупный корень.

Ниже приведен небольшой пример кода:

Контроллер

Namespace Controllers
    Public Class HomeController
        Inherits System.Web.Mvc.Controller

        Function Index() As ActionResult
            Return View(New Models.HomeViewModel)
        End Function

    End Class
End Namespace

Модель

Namespace Models
    Public Class HomeViewModel

        Private _Service As CustomerService
        Public Property Customers As List(Of Customer)

        Public Sub New()
            _Service = New CustomerService
            _Customers = _Service.GetCustomersByBusinessName("Striano")

        End Sub

    End Class
End Namespace

Услуги

Public Class CustomerService
    Private _Repository As ICustomerRepository

    Public Sub New()
        _Repository = New CustomerRepository

    End Sub

    Function GetCustomerByID(ByVal ID As Integer) As Customer
        Return _Repository.GetByID(ID)
    End Function

    Function GetCustomersByBusinessName(ByVal Name As String) As List(Of Customer)
        Return _Repository.Query(Function(x) x.CompanyName.StartsWith(Name)).ToList

    End Function

End Class

Репозиторий

Namespace Data.Repositories
    Public Class CustomerRepository
        Implements ICustomerRepository

        Public Sub Add(ByVal Entity As Business.Customer) Implements IRepository(Of Business.Customer).Add

        End Sub

        Public Sub Delete(ByVal Entity As Business.Customer) Implements IRepository(Of Business.Customer).Delete

        End Sub

        Public Function GetByID(ByVal ID As Integer) As Business.Customer Implements IRepository(Of Business.Customer).GetByID
            Using db As New GTGContainer
                Return db.Customers.FirstOrDefault(Function(x) x.ID = ID)
            End Using
        End Function

        Public Function Query(ByVal Predicate As System.Linq.Expressions.Expression(Of System.Func(Of Business.Customer, Boolean))) As System.Linq.IQueryable(Of Business.Customer) Implements IRepository(Of Business.Customer).Query
            Using db As New GTGContainer
                Return db.Customers.Where(Predicate)
            End Using
        End Function

        Public Sub Save(ByVal Entity As Business.Customer) Implements IRepository(Of Business.Customer).Save

        End Sub
    End Class
End Namespace

1 Ответ

2 голосов
/ 21 февраля 2011

Разделение вашего проекта очень хорошее и содержит именно те слои, которые должны. Проблема в том, что у вас есть сильная связь между слоями, что делает ваш код невозможным для модульного тестирования.

Примеры:

Ваша модель представления тесно связана с конкретной реализацией службы:

_Service = New CustomerService

Ваш сервис тесно связан с конкретной реализацией хранилища:

_Repository = New CustomerRepository

Чтобы улучшить этот код и ослабить связь, вы должны рассмотреть возможность использования инжектора конструктора и структуры DI.

Так, например, ваш конструктор службы должен принять аргумент ICustomerRepository и назначить ему личное поле вместо жесткого кодирования нового экземпляра вручную. Также попросите ваш сервис реализовать интерфейс и сделать то же самое внедрение конструктора в ваш HomeController конструктор, чтобы он имел доступ к сервису.

...