net database technologies - odbms.org · repository methods and/or applied to iqueryable in client...
TRANSCRIPT
.NET Database Technologies
Entity Framework in Enterprise Applications
ORMs in Enterprise Applications
l Key issues to consider: l Domain
l Granularity of object storage/retrieval l Design of relationships to support storage/
retrieval patterns l Architecture
l Isolate presentation/service layers from dependency on data layer
l Code re-use l Testability
En$ty Framework in Enterprise Applica$ons 2
Domain Driven Design
l Terminology and concepts of DDD can help with design of domain model with persistence in mind
l Model elements correspond to domain classes
l Thinking in terms of DDD elements helps clarify how classes should be related and be mapped to storage
En$ty Framework in Enterprise Applica$ons 3
DDD model elements
l Entity l An Entity is defined by having an Identity and
continuity l Unique within the system
l Value Object l Has no Identity l Represent something by its attributes only l Should probably be immutable - you can create a
new one instead of changing another one
En$ty Framework in Enterprise Applica$ons 4
DDD model elements
l Aggregate l Group of things which belong together l Constituent objects make no sense without their
parent object l Aggregate Root
l Single entity which controls access to an aggregate
l Entity which is dealt with by a Repository l Should not have relationships between entities in
different aggregates which are not the roots En$ty Framework in Enterprise Applica$ons
5
Finding aggregates
l Identifying aggregates can help to: l Verify that relationships within the domain model
are valid and establish their directionality l Clarify how those relationships should be
implemented l Choose which entities to expose to the layers
which consume the domain model through repositories
En$ty Framework in Enterprise Applica$ons 6
Finding aggregates: example
l Department as root
l Employee only exists as part of a Department, application works with Department as a whole
En$ty Framework in Enterprise Applica$ons 7
Finding aggregates: example
l Department, Employee as roots
l Better choice if application needs to work directly with
Employees, existence doesn’t depend on Department En$ty Framework in Enterprise Applica$ons
8
Aggregates and relationships
l Relationships between aggregates only through roots
l Can be useful to make these bidirectional and include FK property if you know you will use an ORM for persistence
l Relationships within aggregates often can be unidirectional, from parent to child
En$ty Framework in Enterprise Applica$ons 9
Classes within an aggregate
l Can be Entity or Value Object as appropriate l Address and PostCode are probably value
objects here l Example of entities within an aggregate might
be OrderLines within Order l Identifying this can guide implementation for
ORM, but may not want to match exactly in practice
En$ty Framework in Enterprise Applica$ons 10
Classes within an aggregate
l Address has an Id, so will be treated as an entity in EF, rather than a complex type
l Determines storage in database, will be stored in separate table
l Identity has no particular meaning unless we intend it to be significant when Employees have the same Address - would be another aggregate in that case
l Could enforce one-to-one in mapping
En$ty Framework in Enterprise Applica$ons 11
Repositories
l Domain will require repositories for the aggregate roots: l EmployeeRepository l DepartmentRepository*
l Can store and retrieve Employee objects through EmployeeRepository without materialising related Department object
l Can set relationship using FK property in Employee if ORM supports this
*not implemented in sample code En$ty Framework in Enterprise Applica$ons
12
Repository design
l DbContext and DbSet provide ready-made implementations of Unit of Work and Respository patterns
l Create our own implementations with the following goals: l Provide abstractions which remove dependency
of service/presentation layer on data layer l Separation of concerns, e.g. query logic l Testability
En$ty Framework in Enterprise Applica$ons 13
Dependencies and the onion architecture
l Code should only depend on components closer to the core
l Presentation, service layer and domain code should not depend on infrastructure
l Infrastructure should be injected into other layers as required at runtime
l See jeffreypalermo.com
En$ty Framework in Enterprise Applica$ons 14
Sample code l EnterpriseExample is an ASP.NET MVC4
application l Class library projects for domain, data layers l No separate service layer, controllers
consume domain directly l Code is not intended to be a definitive
exemplar of best practice l Illustrates a range of issues and solutions l Understand the issues and come to your own
conclusion on your favoured implementation En$ty Framework in Enterprise Applica$ons
15
Generic repository
l Most repositories will perform the same basic tasks for their own entity
l Some specific functionality may depend on the nature of the entity or on the way we want to expose that entity
l Use generic repository base class with specific implementations derived from this
En$ty Framework in Enterprise Applica$ons 16
Repository interfaces
l Within domain model express the repositories as interfaces
En$ty Framework in Enterprise Applica$ons 17
These methods may depend on specific details of the Employee class
Interface and implementation
l Repository interface IEmployeeRepository is part of domain model, following DDD practice
l Concrete repository EmployeeRepository is infrastructure, uses EF for data access l Can itself depend on Employee class, which is
part of domain model, closer to core
En$ty Framework in Enterprise Applica$ons 18
Repository implementations
l Generic base repository for EF
En$ty Framework in Enterprise Applica$ons 19
encapsulates a DbContext
Repository implementations
l Specific repository
En$ty Framework in Enterprise Applica$ons 20
Specific fetch strategy implemented for Employee
Unit of Work design
l Relationship between Unit of Work and Repository is ambiguous
l Can implement as UoW which encapsulates one or more repositories
l e.g. DbContext and DbSets l UoW is exposed to client code, which
accesses repositories as properties of the UoW
En$ty Framework in Enterprise Applica$ons 21
Unit of Work design
l Alternatively, each repository encapsulates a UoW to which it delegates responsibility for storing and retrieving entities
l Repository is exposed to client code l In sample code, repository encapsulates a
UoW class derived from DbContext l Could have further abstraction with UoW
class which has a DbContext property
En$ty Framework in Enterprise Applica$ons 22
Unit of Work implementation
l Subclass of DbContext (BaseContext is derived from DbContext – see later)
l Implements a unit of work interface
En$ty Framework in Enterprise Applica$ons 23
Dependency injection
l UoW interface implemented by context class l Here used primarily to allow constructor
dependency injection l UoW into repository, repository into controller l Promotes testability l Using StructureMap.MVC4 in sample code
En$ty Framework in Enterprise Applica$ons 24
Dependency injection object lifetime
l Most IoC containers allow control of lifetime, or scope, of instantiated object
l Transient l Fresh instance every time
l HTTP Request (HttpScoped in SM) l Single instance for each HTTP request, useful in
web app especially if using multiple repositories in a single request, will have same underlying context
l Singleton, Thread En$ty Framework in Enterprise Applica$ons
25
Dependency injection object lifetime - disposing
l Contexts should be disposed when no longer needed
l DbContext (and hence derived classes) implements IDisposable
l With StructureMap, can do this in global.asax
En$ty Framework in Enterprise Applica$ons 26
Repository methods – returning IQueryable or IEnumerable
l IQueryable l Defers query execution l Allows client code to apply (additional) query and
fetch strategy l Underlying context must still be open when values
are used in client l IEnumerable
l Query executes before returning l Query logic/fetch strategy must be encapsulated
in repository En$ty Framework in Enterprise Applica$ons
27
Queries
l Query logic can be applied in specific repository methods and/or applied to IQueryable in client code l Repository can encapsulate the entity set and all
queries on those entities which are required l Or, repository can simply provide access to the
entity set and allow external queries to be applied l Query logic can be LINQ expressions or
separated out into Query Objects
En$ty Framework in Enterprise Applica$ons 28
Repository methods and queries
En$ty Framework in Enterprise Applica$ons 29
GenericRepository
Controller
simple expression stated explicitly here, but could have expression returned by query object with AsExpression method, as shown in Query Objects examples
Repository method allows predicate to be defined by client code
Repository methods and queries
En$ty Framework in Enterprise Applica$ons 30
GenericRepository
Controller
Repository method allows fetch strategy to be defined by client code
Repository methods and queries
En$ty Framework in Enterprise Applica$ons 31
Controller
Query defined by client code using ‘Query Object’ extension method
Insert or update pattern
En$ty Framework in Enterprise Applica$ons 32
EmployeeRepository
Controller
can be used in both Create and Edit code
Notes on implementation
l GetSingle fetches Address with Employee, so Details page can include Address details
l PostCode is a Complex Type so is fetched with Address anyway
l Editing Address actually creates a new Address object (value object), attaches to Employee and saves Employee (aggregate root)
En$ty Framework in Enterprise Applica$ons 33
Bounded contexts in DDD l Multiple models are in play on any large
project, yet when code based on distinct models is combined, software becomes buggy, unreliable, and difficult to understand
l Bounded Context is the delimited applicability of a particular model
l Defines scope of the ubiquitous language l Gives team members a clear and shared
understanding of what has to be consistent and what can develop independently
l En$ty Framework in Enterprise Applica$ons 34
Entities in bounded contexts l An entity may have different significance in
different contexts l For example, in HR context (model used up
to now) full information about and Employee is important, but in Payroll processing context, only the salary grade is important
l Can separate project into different models for each context, each with its own Employee object
l May map to same table in database En$ty Framework in Enterprise Applica$ons
35
Entities in bounded contexts
En$ty Framework in Enterprise Applica$ons 36
Payroll processing domain
• Department is aggregate root • In this context we are simply processing the payroll for
a whole Department at a time • No need to access or store Employee individually
unidirectional relationship, no FK property needed
Implementing bounded contexts
l Each bounded context can have its own EF context
l Some overuse of the word “context”… l Define base context class so all contexts in a
solution can use the same database
En$ty Framework in Enterprise Applica$ons 37
Automated testing
l Unit testing l No database access l Test query logic encapsulated in query objects l Test repositories (need fake/mock context) l Test controllers (need fake/mock repository)
l Integration testing l Test integration with database l Need careful database initialisation
En$ty Framework in Enterprise Applica$ons 38
Example – testing query logic
En$ty Framework in Enterprise Applica$ons 39
omitted full code for test objects here …
Example – testing MVC controller
En$ty Framework in Enterprise Applica$ons 40
fake repository, GetAll returns IQueryable so can test that controller applies further filtering correctly
What’s next?
l Round up of Entity Framework issues l Validation l Concurrency management l etc.
En$ty Framework in Enterprise Applica$ons 41