Below is the series outline; again, this is Part 2.
- Part 1: Setup
- This post involves downloading and creating the SQL Server database, setting up the Visual Studio solution and project structure, and generating the out-of-the-box Entity Framework (EF/EF4) data model from the newly created database.
- Part 2: Creating the Repositories and Unit of Work (UoW)
- This is the meat of the series. This post includes downloading some T4 templates, settings a few parameters, and generating the Repositories and Unit of Work (UoW) using the T4 templates and EF4 data model.
- Part 3: Review Some of The Generated Code
- This post will review a few of the generated class/interfaces that the T4 code generation created.
- Part 4: Using EF, Repository & UoW in an ASP.NET MVC 3 Project
- This post includes wiring up the EF4 data model, repositories, and UoW to StructureMap dependency injection container and use of these products in an ASP.NET MVC 3 Web application project.
- Domain.Poco.tt
- This template generates the POCO (Domain) classes from your EF data model.
- Domain.Poco.Metadata.tt
- This template generates data annotations/metadata ‘buddy’ classes for the POCOs.
- Repository.Interface.tt
- This template generates all the associated Repository Interfaces/Contracts, including:
- base IReadOnlyRepository and IRepository Interfaces
- IUnitOfWork Interface
- I<POCO_ClassName>Repository Interface for each POCO class generated from you EF data model.
- base IReadOnlyRepository and IRepository Interfaces
- This template generates all the associated Repository Interfaces/Contracts, including:
- Repository.Implementation.EF.tt
- This template generates the EF-related concrete class implementations defined by the IRepository Interfaces/Contracts.
- Services.Interface.tt
- This template generates a light-weight Service Interfaces/Contracts for each POCO class.
- Services.Implementation.tt
- This template generates the concrete class implementation defined by the Service Interfaces/Contracts.
- prepareT4Templates.ps1
- This is just a simple PowerShell script that contains project-specific settings to assist in generation T4 templates specific to the project – in our scenario, the Chinook application solution.
#***************************************************************** #***************************************************************** #*********** BEGIN Template Parameters *************************** #***************************************************************** # path to the project's edmx data model (entity framework data model) $edmxFilePath = "..\..\Chinook.Data.Ef\Chinook.edmx" # the namepace name where the solution's domain models live $domainModelNamespace = "Chinook.Core.Domain" # the namespace name where the solution's services will live $serviceInterfaceNamespace = "Chinook.Core.Services" # the namespace name where the solution's repository will live $repositoryInterfaceNamespace = "Chinook.Core.Repository" #***************************************************************** #*********** END Template Parameters ***************************** #***************************************************************** function createDirectory($directory){ New-Item $directory -type directory -force } function removeDestinationFile($file){ if(Test-Path $file){ Remove-Item $file } } function writeout($file){ $sourceFile = "Source/" + $file $destinationDirectory = "Solution/" $destinationFile = $destinationDirectory + $file createDirectory($destinationDirectory) removeDestinationFile($destinationFile) (Get-Content $sourceFile) | Foreach-Object {$_ -replace "\[\*\*EDMX_FILE_PATH\*\*\]", $edmxFilePath} | Foreach-Object {$_ -replace "\[\*\*DOMAIN_MODEL_NAMESPACE\*\*\]", $domainModelNamespace} | Foreach-Object {$_ -replace "\[\*\*SERVICE_INTERFACE_NAMESPACE\*\*]", $serviceInterfaceNamespace} | Foreach-Object {$_ -replace "\[\*\*REPOSITORY_INTERFACE_NAMESPACE\*\*\]", $repositoryInterfaceNamespace} | Set-Content $destinationFile } $files = @("Domain.Poco.tt", "Domain.Poco.Metadata.tt", "Repository.Interface.tt", "Service.Interface.tt", "Repository.Implementation.EF.tt", "Service.Implementation.tt") foreach($file in $files){ writeout($file) }
Directory | Namespace |
Domain | Chinook.Core.Domain |
Repository | Chinook.Core.Repository |
Services | Chinook.Core.Services |
- $edmxFilePath
- relative path to the solution’s EF data model (edmx)
- $domainModelNamespace
- the namespace where the solution’s POCO’s live – see namespace table above
- $serviceInterfaceNamespace
- the namespace where the solution’s Service Interfaces/Contracts live – see namespace table above
- $repositoryInterfaceNamespace
- the namespace where the solution’s Repository Interfaces/Contracts live – see namespace table above
File C:\Chinook\T4_EF4_Repository\prepareT4Templates.ps1 cannot be loaded. The file C:\Chinook\T4_EF4_Repository\prepareT4Templates.ps1 is not digitally signed. The script will not execute on the system. Please see "get-help about_signing" for more details..
You have a couple choices to get around this, but the easiest is to set the PowerShell execution policy to ‘unrestricted’ using the following PowerShell command (* you must be running PowerShell as an Administrator). Go ahead and run this command in the PowerShell console in the bottom pane of the PowerShell editor:
Set-ExecutionPolicy UnRestricted
Set-ExecutionPolicy Restricted
Adding the POCO Template
- Open up the Chinook.edmx file so the EF data model is visible in the designer (this is located in the Chinook.Data.EF project)
- Right-click on an empty area of the EF data model canvas and select ‘Add Code Generation Item…’
- This will bring up the ‘Add new Item Dialog,’ in which you will choose the ADO.NET POCO Entity Generator template (via the Installed Templates –> Code node)
- Set the ‘Name’ of the ADO.NET POCO Entity Generator item to ‘Poco.tt’
- Save the EF data model (edmx file) and build the Chinook.Data.EF project.
- Delete the Poco.tt file from the Chinook.Data.EF project
- ** DO NOT delete the Poco.Context.tt file.
Add the T4 Templates to the Solution
We are now going to add the T4 templates that we generated earlier.Project | Directory | T4 Template (Solution directory) |
Chinook.Core | Domain | Domain.Poco.tt |
Chinook.Core | Domain | Domain.Poco.Metadata.tt |
Chinook.Core | Repository | Repository.Interface.tt |
Chinook.Core | Services | Service.Interface.tt |
Chinook.Data.EF | * add using Project node * | Repository.Implementation.EF.tt |
Chinook.Infrastructure | Services | Service.Implementation.tt |
- You may need to use the ‘All File(*.*)’ filter on the ‘Add Existing Item’ dialog.
- Ensure that you select the proper T4 templates (e.g. use the ‘Solution’ directory and NOT the ‘Source’ directory)
Build the Solution and Resolve Dependencies
Now, go ahead and build the solution and resolve any dependencies that appear in the Error List. You will get errors on the ‘ObjectContext’ derived class (ChinookEntities in our scenario). To resolve these errors, you will need to add a reference to the Domain namespace where the POCOs classes live (we identified this earlier in the ‘namespace’ table). In our scenario, just add the following using statement to the ‘ChinookEntities’ class…using Chinook.Core.Domain;
In the next post in this series, we will review a few of the generated class/interfaces that the T4 code generation templates created.
Thanks for reading…
2 comments:
I had some difficulty getting the paths to work (I'm using a slighly different setup to the one suggested). Eventually I ended up modifying the templates using the following approach - http://stackoverflow.com/questions/3548026/get-referenced-projects-path-in-t4-template/14304115#14304115
Post a Comment