3

私は、EF4 を使用するときにコンテキストを管理するために他の人が何をしているのかについてのフィードバックを探していました。Unit of Work、Service Layer、Repository、EF4 w/POCOテクニックを使用して(私は思う:))、MVCアプリを作成しています。

私のコントローラーは、UOWを取るサービスを利用し、リポジトリを利用してEFからPOCOを取得します。

これは正しく実装されていますか?

以下をご覧ください。フィードバックをお待ちしております!!

コントローラ

Public Class MyController
    Function ListCustomers() As ActionResult
        Dim _UOW = New UnitOfWork
        Dim _Service = New CustomerService(_UOW)
        Dim _Model = New CustomersViewModel
        _Model.Customers = _Service.GetCustomers
        _UOW.Dispose()

        Return View(_Model)
    End Function
End Class

作業単位

Public Interface IUnitOfWork
    Property Context As GTGContext
    Sub Committ()

End Interface

Public Class UnitOfWork
    Implements IDisposable, IUnitOfWork

    Public Property Context As Domain.GTGContext Implements IUnitOfWork.Context

    Public Sub New()
        _Context = New GTGContext

    End Sub

    Public Sub Committ() Implements IUnitOfWork.Committ
        _Context.SaveChanges()

    End Sub

#Region "IDisposable Support"

    Private _IsDisposed As Boolean

    Protected Overridable Sub Dispose(ByVal Disposing As Boolean)
        If (Not _IsDisposed) Then
            If (Disposing) Then
                If (_Context IsNot Nothing) Then
                    _Context.Dispose()
                End If
            End If

            'TODO: Free unmanaged resources (unmanaged objects) and override Finalize() below.
        End If

        _IsDisposed = True

    End Sub

    'TODO: Override Finalize() only if Dispose(ByVal disposing As Boolean) above has code to free unmanaged resources.
    'Protected Overrides Sub Finalize()
    '    Dispose(False)
    '    MyBase.Finalize()
    'End Sub

    Public Sub Dispose() Implements IDisposable.Dispose
        Dispose(True)
        GC.SuppressFinalize(Me)

    End Sub

#End Region

End Class

サービス

Public Class CustomerService
    Private _UOW As IUnitOfWork
    Private _Repo As Repository(Of Customer)

    Public Sub New(UOW As IUnitOfWork)
        _UOW = UOW
        _Repo = New Repository(Of Customer)(_UOW)
    End Sub

    Public Function GetCustoemrs() As IQueryable(Of Customer)
        ' Any Business Logic Here
        Return _Repo.GetCustomers()
    End Function

End Class

リポジトリ

Imports System.Data.Objects

Namespace Repositories
    Public Interface IRepository(Of T As Class)
        ReadOnly Property ObjectSet As IObjectSet(Of T)
        ReadOnly Property UnitOfWork As IUnitOfWork
        Function Query(ByVal Expression As Expressions.Expression(Of Func(Of T, Boolean))) As IQueryable(Of T)
        Function GetFirst(ByVal Expression As Expressions.Expression(Of Func(Of T, Boolean))) As T
        Function GetSingle(ByVal Expression As Expressions.Expression(Of Func(Of T, Boolean))) As T
        Sub Add(ByVal Entity As T)
        Sub Attach(ByVal Entity As T)
        Sub Delete(ByVal Entity As T)
        Sub SaveChanges()

    End Interface

    Public Class Repository(Of T As Class)
        Implements IRepository(Of T)

#Region "Private Members/Properties"

        Private _ObjectSet As IObjectSet(Of T)
        Private ReadOnly Property ObjectSet As System.Data.Objects.IObjectSet(Of T) Implements IRepository(Of T).ObjectSet
            Get
                If (_ObjectSet Is Nothing) Then
                    _ObjectSet = UnitOfWork.Context.CreateObjectSet(Of T)()
                End If
                Return _ObjectSet
            End Get
        End Property

        Private _UnitOfWork As IUnitOfWork
        Private ReadOnly Property UnitOfWork As IUnitOfWork Implements IRepository(Of T).UnitOfWork
            Get
                Return _UnitOfWork
            End Get
        End Property

#End Region

#Region "Constructor(s)"

        Public Sub New(ByVal UnitOfWork As IUnitOfWork)
            If (UnitOfWork Is Nothing) Then
                Throw New ArgumentNullException("UnitOfWork")
            End If
            _UnitOfWork = UnitOfWork

        End Sub

#End Region

#Region "IRepository(Of T)"

        Public Sub Add(ByVal Entity As T) Implements IRepository(Of T).Add
            ObjectSet.AddObject(Entity)

        End Sub

        Public Sub Attach(ByVal Entity As T) Implements IRepository(Of T).Attach
            ObjectSet.Attach(Entity)
            UnitOfWork.Context.ObjectStateManager.ChangeObjectState(Entity, EntityState.Modified)

        End Sub

        Public Sub Delete(ByVal Entity As T) Implements IRepository(Of T).Delete
            ObjectSet.DeleteObject(Entity)

        End Sub

        Public Function GetFirst(ByVal Expression As System.Linq.Expressions.Expression(Of System.Func(Of T, Boolean))) As T Implements IRepository(Of T).GetFirst
            Return ObjectSet.FirstOrDefault(Expression)

        End Function

        Public Function GetSingle(ByVal Expression As System.Linq.Expressions.Expression(Of System.Func(Of T, Boolean))) As T Implements IRepository(Of T).GetSingle
            Return ObjectSet.SingleOrDefault(Expression)

        End Function

        Public Function Query(ByVal Expression As System.Linq.Expressions.Expression(Of System.Func(Of T, Boolean))) As System.Linq.IQueryable(Of T) Implements IRepository(Of T).Query
            Return ObjectSet.Where(Expression)

        End Function

        Public Sub SaveChanges() Implements IRepository(Of T).SaveChanges
            UnitOfWork.Committ()

        End Sub

#End Region

    End Class
End Namespace
4

1 に答える 1

2

教えてください、私は長い間、主にStackOverflowでどのアプローチを取るべきか悩んでいました:)

オブジェクト コンテキストの管理に関するこの優れた記事の実装に落ち着きました (複数のコンテキストを許可する修正バージョンに注意してください)。

http://dotnetslackers.com/articles/ado_net/Managing-Entity-Framework-ObjectContext-lifespan-and-scope-in​​-n-layered-ASP-NET-applications.aspx

次に、次のようなファサードを実装しました。

public class MyEntityFacade : FacadeBase<MyEntities, MyEntity>
{
    public object GetAll()
    {
        return this.ObjectContext.MyEntities.ToList();
    }

    public bool HasChild(int parentId)
    {
        return this.ObjectContext.MyEntityChild.Any(c => c.parentId == parentId);
    }
}

確かに、それは古いですが、男の子、男の子、それは動作します!

ほら、サービスレイヤー/作業単位/リポジトリのものすべてで、それをサポートするためだけに非常に多くのコードを書かなければならなくなるということです(そして確かにEF4はコードの肥大化を減らすはずでした!)。新しいエンティティを追加するたびに、何を推測しますか? さらに面倒なコードの肥大化。

上記の方法を使用すると、すべてのファサード/作業単位サポート コードが再利用可能なクラス ライブラリに詰め込まれ、実際に何かを行うコードのみに関係するファサード コードを記述するだけで済みます。コンテキスト。

私にとってはうまくいきます...ああ、「ファサード」という言葉の使用について私を非難しないでください。私は実際に学校に行ったことはありません;)

ありがとう、リチャード

Ps 素晴らしい週末を!

于 2011-09-02T05:15:56.567 に答える