Hizmet Katmanı ile Doğrulama (VB)

ile Stephen Walther

Doğrulama mantığınızı denetleyici eylemlerinizin dışında ve ayrı bir hizmet katmanında nasıl taşıyacağınızı öğrenin. Bu öğreticide, Stephen Walther, hizmet katmanınızı denetleyici katmanınızdan yalıtarak sorunları nasıl keskin bir şekilde koruyabileceğinizi açıklar.

Bu öğreticinin amacı, bir ASP.NET MVC uygulamasında doğrulama gerçekleştirme yöntemini açıklıyor. Bu öğreticide, doğrulama mantığınızı denetleyicilerden ve ayrı bir hizmet katmanına taşımayı öğreneceksiniz.

Kaygıları ayırma

Bir ASP.NET MVC uygulaması oluşturduğunuzda, veritabanı mantığınızı denetleyici eylemlerinizin içine yerleştirmemelisiniz. Veritabanınızı ve denetleyici mantığınızı karıştırmak, uygulamanızın zaman içinde bakımını daha zor hale getirir. Öneri, tüm veritabanı mantığınızı ayrı bir depo katmanında yerleştirmesidir.

Örneğin, Listeleme 1, ProductRepository adlı basit bir depo içerir. Ürün deposu, uygulamanın tüm veri erişim kodunu içerir. Liste ayrıca, ürün deposunun uyguladığı ıproductrepository arabirimini de içerir.

Listeleme 1-Models\productdepotory.exe

Public Class ProductRepository
Implements IProductRepository

    Private _entities As New ProductDBEntities()


Public Function ListProducts() As IEnumerable(Of Product) Implements IProductRepository.ListProducts
    Return _entities.ProductSet.ToList()
End Function


Public Function CreateProduct(ByVal productToCreate As Product) As Boolean Implements IProductRepository.CreateProduct
    Try
        _entities.AddToProductSet(productToCreate)
        _entities.SaveChanges()
        Return True
    Catch
        Return False
    End Try
End Function

End Class

Public Interface IProductRepository
Function CreateProduct(ByVal productToCreate As Product) As Boolean
Function ListProducts() As IEnumerable(Of Product)
End Interface

Listeleme 2 ' deki denetleyici, dizin () ve Create () eylemleri içinde depo katmanını kullanır. Bu denetleyicinin herhangi bir veritabanı mantığı içermediğini unutmayın. Bir depo katmanı oluşturmak, kaygılara yönelik temiz ayrımı korumanıza olanak sağlar. Denetleyiciler, uygulama akış denetim mantığından sorumludur ve veri erişim mantığıyla depo sorumludur.

Listeleme 2-Controllers\productcontroller.exe

Public Class ProductController
Inherits Controller

    Private _repository As IProductRepository

Public Sub New()
    Me.New(New ProductRepository())
End Sub


Public Sub New(ByVal repository As IProductRepository)
    _repository = repository
End Sub


Public Function Index() As ActionResult
    Return View(_repository.ListProducts())
End Function


'
' GET: /Product/Create

Public Function Create() As ActionResult
    Return View()
End Function

'
' POST: /Product/Create

<AcceptVerbs(HttpVerbs.Post)> _
Public Function Create(<Bind(Exclude:="Id")> ByVal productToCreate As Product) As ActionResult
    _repository.CreateProduct(productToCreate)
    Return RedirectToAction("Index")
End Function

End Class

Hizmet katmanı oluşturma

Bu nedenle, uygulama akış denetim mantığı bir denetleyiciye aittir ve veri erişim mantığı bir depoya aittir. Bu durumda, doğrulama mantığınızı nereye yerleştirmeniz gerekir? Bir seçenek, doğrulama mantığınızı bir hizmet katmanınayerleştirmadır.

Bir hizmet katmanı, bir ASP.NET MVC uygulamasındaki bir denetleyici ve depo katmanı arasındaki iletişimi destekleyen ek bir katmandır. Hizmet katmanı iş mantığını içerir. Özellikle, doğrulama mantığını içerir.

Örneğin, kod 3 ' teki ürün hizmeti katmanının bir CreateProduct () yöntemi vardır. CreateProduct () yöntemi, ürünü ürün deposuna geçirmeden önce yeni bir ürünü doğrulamak için ValidateProduct () yöntemini çağırır.

Listeleme 3-Models\productservice.exe

Public Class ProductService
Implements IProductService

Private _modelState As ModelStateDictionary
Private _repository As IProductRepository

Public Sub New(ByVal modelState As ModelStateDictionary, ByVal repository As IProductRepository)
    _modelState = modelState
    _repository = repository
End Sub

Protected Function ValidateProduct(ByVal productToValidate As Product) As Boolean
    If productToValidate.Name.Trim().Length = 0 Then
        _modelState.AddModelError("Name", "Name is required.")
    End If
    If productToValidate.Description.Trim().Length = 0 Then
        _modelState.AddModelError("Description", "Description is required.")
    End If
    If productToValidate.UnitsInStock

Ürün denetleyicisi, kod 4 ' te depo katmanı yerine hizmet katmanını kullanmak üzere güncelleştirilmiştir. Denetleyici katmanı hizmet katmanıyla oynanır. Hizmet katmanı, depo katmanıyla konuşur. Her katmanın ayrı bir sorumluluğu vardır.

Listeleme 4-Controllers\productcontroller.exe

Public Class ProductController
Inherits Controller

Private _service As IProductService

Public Sub New()
    _service = New ProductService(Me.ModelState, New ProductRepository())
End Sub

Public Sub New(ByVal service As IProductService)
    _service = service
End Sub


Public Function Index() As ActionResult
    Return View(_service.ListProducts())
End Function


'
' GET: /Product/Create

Public Function Create() As ActionResult
    Return View()
End Function

'
' POST: /Product/Create

<AcceptVerbs(HttpVerbs.Post)> _
Public Function Create(<Bind(Exclude := "Id")> ByVal productToCreate As Product) As ActionResult
    If Not _service.CreateProduct(productToCreate) Then
        Return View()
    End If
    Return RedirectToAction("Index")
End Function

End Class

Ürün hizmeti 'nin ürün denetleyicisi oluşturucusunda oluşturulmuş olduğuna dikkat edin. Ürün hizmeti oluşturulduğunda, model durum sözlüğü hizmete geçirilir. Ürün hizmeti, doğrulama hata iletilerini denetleyiciye geri geçirmek için model durumunu kullanır.

Hizmet katmanını bağlama

Denetleyiciyi ve hizmet katmanlarını tek bir şekilde yalıtamadı. Denetleyici ve hizmet katmanları, model durumu üzerinden iletişim kurar. Diğer bir deyişle, hizmet katmanının, ASP.NET MVC çerçevesinin belirli bir özelliğine bağımlılığı vardır.

Hizmet katmanını denetleyici katmanımız kadar mümkün olduğunca yalıtmak istiyoruz. Teorik olarak, hizmet katmanını yalnızca bir ASP.NET MVC uygulaması değil, herhangi bir uygulama türüyle kullanabilmelidir. Örneğin, gelecekte uygulamamız için bir WPF ön ucu oluşturmak isteyebilirsiniz. ASP.NET MVC modeli durumundaki bağımlılığı hizmet katmanımızdan kaldırmanın bir yolunu bulduk.

5. listede, hizmet katmanı artık model durumunu kullanmamasını sağlayacak şekilde güncelleştirilmiştir. Bunun yerine, ıvalidationdictionary arabirimini uygulayan herhangi bir sınıfı kullanır.

Listeleme 5-Models\productservice,vb (ayrılmış)

Public Class ProductService
Implements IProductService

Private _validatonDictionary As IValidationDictionary
Private _repository As IProductRepository

Public Sub New(ByVal validationDictionary As IValidationDictionary, ByVal repository As IProductRepository)
    _validatonDictionary = validationDictionary
    _repository = repository
End Sub

Protected Function ValidateProduct(ByVal productToValidate As Product) As Boolean
    If productToValidate.Name.Trim().Length = 0 Then
        _validatonDictionary.AddError("Name", "Name is required.")
    End If
    If productToValidate.Description.Trim().Length = 0 Then
        _validatonDictionary.AddError("Description", "Description is required.")
    End If
    If productToValidate.UnitsInStock

Ivalidationdictionary arabirimi, liste 6 ' da tanımlanmıştır. Bu basit arabirim tek bir yönteme ve tek bir özelliğe sahiptir.

Listeleme 6-Models\IValidationDictionary.cs

Public Interface IValidationDictionary
Sub AddError(ByVal key As String, ByVal errorMessage As String)
ReadOnly Property IsValid() As Boolean
End Interface

ModelStateWrapper sınıfı adlı Listeleme 7 ' deki sınıf ıvalidationdictionary arabirimini uygular. Bir model durum sözlüğünü oluşturucuya geçirerek ModelStateWrapper sınıfının örneğini oluşturabilirsiniz.

Listeleme 7-Models\ModelStateWrapper.vb

Public Class ModelStateWrapper
Implements IValidationDictionary

Private _modelState As ModelStateDictionary

Public Sub New(ByVal modelState As ModelStateDictionary)
    _modelState = modelState
End Sub

#Region "IValidationDictionary Members"

Public Sub AddError(ByVal key As String, ByVal errorMessage As String) Implements IValidationDictionary.AddError
    _modelState.AddModelError(key, errorMessage)
End Sub

Public ReadOnly Property IsValid() As Boolean Implements IValidationDictionary.IsValid
    Get
        Return _modelState.IsValid
    End Get
End Property

#End Region

End Class

Son olarak, liste 8 ' deki güncelleştirilmiş denetleyici, Oluşturucu içinde hizmet katmanını oluştururken ModelStateWrapper kullanır.

8-Controllers\productcontroller.exe listeleme

Public Class ProductController
Inherits Controller

Private _service As IProductService

Public Sub New()
    _service = New ProductService(New ModelStateWrapper(Me.ModelState), New ProductRepository())
End Sub

Public Sub New(ByVal service As IProductService)
    _service = service
End Sub


Public Function Index() As ActionResult
    Return View(_service.ListProducts())
End Function


'
' GET: /Product/Create

Public Function Create() As ActionResult
    Return View()
End Function

'
' POST: /Product/Create

<AcceptVerbs(HttpVerbs.Post)> _
Public Function Create(<Bind(Exclude := "Id")> ByVal productToCreate As Product) As ActionResult
    If Not _service.CreateProduct(productToCreate) Then
        Return View()
    End If
    Return RedirectToAction("Index")
End Function

End Class

Ivalidationdictionary arabirimini ve ModelStateWrapper sınıfını kullanmak, hizmet katmanımızı denetleyici katmanımızdan tamamen yalıtmamızı sağlar. Hizmet katmanı artık model durumuna bağlı değil. Ivalidationdictionary arabirimini uygulayan herhangi bir sınıfı hizmet katmanına geçirebilirsiniz. Örneğin, bir WPF uygulaması, bir basit koleksiyon sınıfıyla ıvalidationdictionary arabirimini uygulayabilir.

Özet

Bu öğreticinin amacı, bir ASP.NET MVC uygulamasında doğrulama gerçekleştirmeye yönelik bir yaklaşımı tartışmaktır. Bu öğreticide, tüm doğrulama mantığınızı denetleyicilerden ve ayrı bir hizmet katmanına nasıl taşıyabileceğinizi öğrendiniz. Ayrıca, bir Modelstatesarmalayıcı sınıfı oluşturarak hizmet katmanınızı denetleyici katmanınızdan yalıtmak için de öğrenirsiniz.