├── .gitignore ├── Besnik.Domain.EntityFramework ├── Besnik.Domain.EntityFramework.csproj ├── Mappings │ └── CustomerConfiguration.cs ├── Properties │ └── AssemblyInfo.cs ├── Repositories │ └── CustomerRepository.cs └── packages.config ├── Besnik.Domain.LinqToSql ├── Besnik.Domain.LinqToSql.csproj ├── Mappings │ └── DataContextMapping.linq2sql.xml ├── Properties │ └── AssemblyInfo.cs └── Repositories │ └── CustomerRepository.cs ├── Besnik.Domain.NHibernate ├── Besnik.Domain.NHibernate.csproj ├── Mappings │ └── Customer.hbm.xml ├── Properties │ └── AssemblyInfo.cs ├── Repositories │ └── CustomerRepository.cs ├── Specifications │ └── CriteriaCustomerSpecification.cs └── packages.config ├── Besnik.Domain ├── Besnik.Domain.csproj ├── Entities │ └── Customer.cs ├── Properties │ └── AssemblyInfo.cs ├── Repositories │ └── ICustomerRepository.cs └── Specifications │ ├── CustomerQueryableSpecification.cs │ └── ICustomerSpecification.cs ├── Besnik.GenericRepository.EntityFramework ├── Besnik.GenericRepository.EntityFramework.csproj ├── EntityFrameworkTransaction.cs ├── EntityFrameworkUnitOfWork.cs ├── EntityFrameworkUnitOfWorkConvertor.cs ├── EntityFrameworkUnitOfWorkFactory.cs ├── Properties │ └── AssemblyInfo.cs └── packages.config ├── Besnik.GenericRepository.LinqToSql ├── Besnik.GenericRepository.LinqToSql.csproj ├── LinqToSqlRepository.cs ├── LinqToSqlTransaction.cs ├── LinqToSqlUnitOfWork.cs ├── LinqToSqlUnitOfWorkConvertor.cs ├── LinqToSqlUnitOfWorkFactory.cs └── Properties │ └── AssemblyInfo.cs ├── Besnik.GenericRepository.NHibernate ├── Besnik.GenericRepository.NHibernate.csproj ├── NHibernateTransaction.cs ├── NHibernateUnitOfWork.cs ├── NHibernateUnitOfWorkConvertor.cs ├── NHibernateUnitOfWorkFactory.cs ├── Properties │ └── AssemblyInfo.cs ├── Specifications │ ├── CriteriaSpecification.cs │ └── CriteriaSpecificationResult.cs └── packages.config ├── Besnik.GenericRepository.Tests ├── Besnik.GenericRepository.Tests.csproj ├── Besnik.GenericRepository.Tests.nunit ├── Config │ ├── App.config │ ├── NHibernate.config │ └── NHibernate.sqlite.config ├── Factory │ └── Factory.cs ├── Fixtures │ ├── EntityFrameworkFixtures │ │ └── EntityFrameworkCustomerRepositoryFixture.cs │ ├── GenericFixtures │ │ ├── BaseUnitOfWorkFixture.cs │ │ └── GenericCustomerRepositoryFixture.cs │ ├── LinqToSqlFixtures │ │ └── LinqToSqlCustomerRepositoryFixture.cs │ └── NHibernateFixtures │ │ ├── NHibernateCriteriaFixture.cs │ │ ├── NHibernateCustomerRepositoryFixture.cs │ │ └── NHibernateUnitOfWorkFixture.cs ├── Mocks │ └── SpecificationLocatorStub.cs ├── Properties │ └── AssemblyInfo.cs └── packages.config ├── Besnik.GenericRepository.sln ├── Besnik.GenericRepository ├── Besnik.GenericRepository.csproj ├── Exceptions │ └── GenericRepositoryException.cs ├── GenericRepository │ └── GenericRepository.cs ├── Interfaces │ ├── IGenericRepository.cs │ ├── ISpecification.cs │ ├── ISpecificationLocator.cs │ ├── ISpecificationResult.cs │ ├── ITransaction.cs │ ├── IUnitOfWork.cs │ ├── IUnitOfWorkConvertor.cs │ └── IUnitOfWorkFactory.cs ├── Properties │ └── AssemblyInfo.cs └── QueryableSpecification │ ├── QueryableSpecification.cs │ └── QueryableSpecificationResult.cs ├── README.md └── packages ├── Autofac.2.6.1.841 ├── Autofac.2.6.1.841.nupkg └── lib │ ├── NET35 │ ├── Autofac.Configuration.dll │ ├── Autofac.dll │ └── Autofac.xml │ ├── NET40 │ ├── Autofac.Configuration.dll │ ├── Autofac.dll │ └── Autofac.xml │ ├── SL3-WP │ ├── Autofac.dll │ └── Autofac.xml │ ├── SL4-WindowsPhone │ ├── Autofac.dll │ └── Autofac.xml │ ├── SL4-WindowsPhone71 │ ├── Autofac.dll │ └── Autofac.xml │ └── SL4 │ ├── Autofac.dll │ └── Autofac.xml ├── EntityFramework.4.3.1 ├── Content │ ├── App.config.transform │ └── Web.config.transform ├── EntityFramework.4.3.1.nupkg ├── lib │ └── net40 │ │ ├── EntityFramework.dll │ │ └── EntityFramework.xml └── tools │ ├── EF4.3on.NET4.5Readme.txt │ ├── EntityFramework.PowerShell.dll │ ├── EntityFramework.psd1 │ ├── EntityFramework.psm1 │ ├── init.ps1 │ ├── install.ps1 │ └── migrate.exe ├── Iesi.Collections.3.2.0.4000 ├── Iesi.Collections.3.2.0.4000.nupkg └── lib │ └── Net35 │ ├── Iesi.Collections.dll │ └── Iesi.Collections.xml ├── NHibernate.3.3.0.4000 ├── ConfigurationTemplates │ ├── FireBird.cfg.xml │ ├── MSSQL.cfg.xml │ ├── MySql.cfg.xml │ ├── Oracle.cfg.xml │ ├── PostgreSQL.cfg.xml │ ├── SQLite.cfg.xml │ ├── SybaseASE.cfg.xml │ └── SybaseSQLAnywhere.cfg.xml ├── NHibernate.3.3.0.4000.nupkg ├── NHibernate.license.txt ├── NHibernate.readme.html ├── NHibernate.releasenotes.txt ├── lib │ └── Net35 │ │ ├── NHibernate.dll │ │ └── NHibernate.xml ├── nhibernate-configuration.xsd └── nhibernate-mapping.xsd ├── NHibernate.Linq.1.0 ├── NHibernate.Linq.1.0.nupkg └── lib │ ├── NHibernate.Linq.dll │ └── NHibernate.Linq.xml ├── NUnit.2.6.0.12054 ├── NUnit.2.6.0.12054.nupkg ├── lib │ ├── nunit.framework.dll │ └── nunit.framework.xml └── license.txt ├── System.Data.SQLite.1.0.80.0 ├── System.Data.SQLite.1.0.80.0.nupkg └── lib │ ├── net20 │ ├── System.Data.SQLite.Linq.dll │ └── System.Data.SQLite.dll │ └── net40 │ ├── System.Data.SQLite.Linq.dll │ └── System.Data.SQLite.dll ├── log4net.2.0.0 ├── lib │ ├── net10-full │ │ ├── log4net.dll │ │ └── log4net.xml │ ├── net11-full │ │ ├── log4net.dll │ │ └── log4net.xml │ ├── net20-cf │ │ ├── log4net.dll │ │ └── log4net.xml │ ├── net20-full │ │ ├── log4net.dll │ │ └── log4net.xml │ ├── net35-client │ │ ├── log4net.dll │ │ └── log4net.xml │ ├── net35-full │ │ ├── log4net.dll │ │ └── log4net.xml │ ├── net40-client │ │ ├── log4net.dll │ │ └── log4net.xml │ └── net40-full │ │ ├── log4net.dll │ │ └── log4net.xml └── log4net.2.0.0.nupkg └── repositories.config /.gitignore: -------------------------------------------------------------------------------- 1 | # Build Folders (you can keep bin if you'd like, to store dlls and pdbs) 2 | [Oo]bj 3 | [Bb]in 4 | *.user 5 | *.suo 6 | *.[Cc]ache 7 | *.bak 8 | *.ncb 9 | *.log 10 | *.DS_Store 11 | [Tt]humbs.db 12 | _ReSharper.* 13 | *.resharper 14 | Ankh.NoLoad 15 | 16 | # mstest test results 17 | TestResults -------------------------------------------------------------------------------- /Besnik.Domain.EntityFramework/Besnik.Domain.EntityFramework.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {B3288165-24F4-49AF-A7B5-79B027F82EC8} 9 | Library 10 | Properties 11 | Besnik.Domain.EntityFramework 12 | Besnik.Domain.EntityFramework 13 | v4.0 14 | 512 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | 25 | 26 | pdbonly 27 | true 28 | bin\Release\ 29 | TRACE 30 | prompt 31 | 4 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | {D5B52DDB-C986-4055-9CAC-5526F42B8A93} 41 | Besnik.Domain 42 | 43 | 44 | {5630007D-50C9-4D99-A734-BBE7451B1C3D} 45 | Besnik.GenericRepository.EntityFramework 46 | 47 | 48 | {1C33F903-59B8-437C-8637-94CB394CA970} 49 | Besnik.GenericRepository 50 | 51 | 52 | 53 | 54 | ..\packages\EntityFramework.4.3.1\lib\net40\EntityFramework.dll 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 71 | -------------------------------------------------------------------------------- /Besnik.Domain.EntityFramework/Mappings/CustomerConfiguration.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data.Entity.ModelConfiguration; 3 | 4 | namespace Besnik.Domain.EntityFramework 5 | { 6 | public class CustomerConfiguration : EntityTypeConfiguration 7 | { 8 | /// 9 | /// Constructor. 10 | /// 11 | /// 12 | /// Make sure to update also EntityFrameworkCustomerRepositoryFixture.cs 13 | /// and InitializeDataStorage() method that clears db before each test. 14 | /// 15 | public CustomerConfiguration() 16 | { 17 | HasKey(c => c.Id); 18 | Property(c => c.Name).HasMaxLength(255); 19 | 20 | this.Map( 21 | config => { 22 | config.Properties(c => new 23 | { 24 | Id = c.Id, 25 | Name = c.Name, 26 | Age = c.Age 27 | }); 28 | 29 | config.ToTable("Customers"); 30 | } 31 | ); 32 | } 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /Besnik.Domain.EntityFramework/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Besnik.Domain.EntityFramework")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("")] 13 | [assembly: AssemblyCopyright("")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("bfe9fdf6-8912-4b38-9472-9ed42b4be99a")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.1.0.*")] 36 | [assembly: AssemblyFileVersion("1.1.0.0")] 37 | -------------------------------------------------------------------------------- /Besnik.Domain.EntityFramework/Repositories/CustomerRepository.cs: -------------------------------------------------------------------------------- 1 | using Besnik.GenericRepository; 2 | 3 | namespace Besnik.Domain.EntityFramework 4 | { 5 | /// 6 | /// Customer repository based on Entity Framework. 7 | /// 8 | public class CustomerRepository : GenericRepository, ICustomerRepository 9 | { 10 | /// 11 | /// Constructor. 12 | /// 13 | public CustomerRepository(IUnitOfWork unitOfWork, ISpecificationLocator specificationLocator) 14 | : base(unitOfWork, specificationLocator) 15 | { 16 | } 17 | 18 | } 19 | } 20 | 21 | -------------------------------------------------------------------------------- /Besnik.Domain.EntityFramework/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Besnik.Domain.LinqToSql/Besnik.Domain.LinqToSql.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.30729 7 | 2.0 8 | {C6CC3E66-9506-43D7-BE8F-0C49D59C34E3} 9 | Library 10 | Properties 11 | Besnik.Domain.LinqToSqlRepository 12 | Besnik.Domain.LinqToSqlRepository 13 | v4.0 14 | 512 15 | 16 | 17 | 3.5 18 | 19 | publish\ 20 | true 21 | Disk 22 | false 23 | Foreground 24 | 7 25 | Days 26 | false 27 | false 28 | true 29 | 0 30 | 1.0.0.%2a 31 | false 32 | false 33 | true 34 | 35 | 36 | 37 | true 38 | full 39 | false 40 | bin\Debug\ 41 | DEBUG;TRACE 42 | prompt 43 | 4 44 | AllRules.ruleset 45 | 46 | 47 | pdbonly 48 | true 49 | bin\Release\ 50 | TRACE 51 | prompt 52 | 4 53 | AllRules.ruleset 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | {D5B52DDB-C986-4055-9CAC-5526F42B8A93} 64 | Besnik.Domain 65 | 66 | 67 | {207ADEBC-CCE9-4ACC-AEA8-E086BB23A638} 68 | Besnik.GenericRepository.LinqToSql 69 | 70 | 71 | {1C33F903-59B8-437C-8637-94CB394CA970} 72 | Besnik.GenericRepository 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | False 84 | .NET Framework 3.5 SP1 Client Profile 85 | false 86 | 87 | 88 | False 89 | .NET Framework 3.5 SP1 90 | true 91 | 92 | 93 | False 94 | Windows Installer 3.1 95 | true 96 | 97 | 98 | 99 | 106 | -------------------------------------------------------------------------------- /Besnik.Domain.LinqToSql/Mappings/DataContextMapping.linq2sql.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
10 |
-------------------------------------------------------------------------------- /Besnik.Domain.LinqToSql/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Besnik.Domain.LinqToSqlRepository")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("")] 13 | [assembly: AssemblyCopyright("")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("ddca00e4-17fe-4886-9357-cbb4a57fe5fa")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.1.0.*")] 36 | [assembly: AssemblyFileVersion("1.1.0.0")] 37 | -------------------------------------------------------------------------------- /Besnik.Domain.LinqToSql/Repositories/CustomerRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq.Expressions; 3 | using Besnik.GenericRepository; 4 | using Besnik.GenericRepository.LinqToSql; 5 | 6 | namespace Besnik.Domain.LinqToSqlRepository 7 | { 8 | /// 9 | /// Customer repository based on LinqToSql technology. 10 | /// 11 | public class CustomerRepository : LinqToSqlRepository, ICustomerRepository 12 | { 13 | /// 14 | /// Constructor. 15 | /// 16 | public CustomerRepository(IUnitOfWork unitOfWork, ISpecificationLocator specificationLocator) 17 | : base(unitOfWork, specificationLocator) 18 | { 19 | } 20 | 21 | /// 22 | /// Gets predicate that filters entity using given id. 23 | /// 24 | protected override Expression> FirstOrDefaultPredicate(int id) 25 | { 26 | return c => c.Id == id; 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Besnik.Domain.NHibernate/Besnik.Domain.NHibernate.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.30729 7 | 2.0 8 | {ABDD5544-3CAA-49FB-A06A-895585BA55B2} 9 | Library 10 | Properties 11 | Besnik.Domain.NHibernateRepository 12 | Besnik.Domain.NHibernateRepository 13 | v4.0 14 | 512 15 | 16 | 17 | 3.5 18 | 19 | publish\ 20 | true 21 | Disk 22 | false 23 | Foreground 24 | 7 25 | Days 26 | false 27 | false 28 | true 29 | 0 30 | 1.0.0.%2a 31 | false 32 | false 33 | true 34 | 35 | 36 | 37 | true 38 | full 39 | false 40 | bin\Debug\ 41 | DEBUG;TRACE 42 | prompt 43 | 4 44 | AllRules.ruleset 45 | 46 | 47 | pdbonly 48 | true 49 | bin\Release\ 50 | TRACE 51 | prompt 52 | 4 53 | AllRules.ruleset 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | {D5B52DDB-C986-4055-9CAC-5526F42B8A93} 63 | Besnik.Domain 64 | 65 | 66 | {DCC5973E-B6BC-4A41-8996-ED4AFBEEB318} 67 | Besnik.GenericRepository.NHibernate 68 | 69 | 70 | {1C33F903-59B8-437C-8637-94CB394CA970} 71 | Besnik.GenericRepository 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | False 80 | .NET Framework 3.5 SP1 Client Profile 81 | false 82 | 83 | 84 | False 85 | .NET Framework 3.5 SP1 86 | true 87 | 88 | 89 | False 90 | Windows Installer 3.1 91 | true 92 | 93 | 94 | 95 | 96 | ..\packages\Iesi.Collections.3.2.0.4000\lib\Net35\Iesi.Collections.dll 97 | 98 | 99 | False 100 | ..\packages\NHibernate.3.3.0.4000\lib\Net35\NHibernate.dll 101 | 102 | 103 | 104 | 105 | 106 | 107 | 114 | -------------------------------------------------------------------------------- /Besnik.Domain.NHibernate/Mappings/Customer.hbm.xml: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | -------------------------------------------------------------------------------- /Besnik.Domain.NHibernate/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Besnik.Domain.NHibernateRepository")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("")] 13 | [assembly: AssemblyCopyright("")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("511cee4d-c23b-4e73-8cb8-f32c294912f9")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.1.0.*")] 36 | [assembly: AssemblyFileVersion("1.1.0.0")] 37 | -------------------------------------------------------------------------------- /Besnik.Domain.NHibernate/Repositories/CustomerRepository.cs: -------------------------------------------------------------------------------- 1 | using Besnik.GenericRepository; 2 | 3 | namespace Besnik.Domain.NHibernateRepository 4 | { 5 | /// 6 | /// Customer repository based on NHibernate. 7 | /// 8 | public class CustomerRepository : GenericRepository, ICustomerRepository 9 | { 10 | /// 11 | /// Constructor. 12 | /// 13 | public CustomerRepository(IUnitOfWork unitOfWork, ISpecificationLocator specificationLocator) 14 | : base(unitOfWork, specificationLocator) 15 | { 16 | } 17 | 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Besnik.Domain.NHibernate/Specifications/CriteriaCustomerSpecification.cs: -------------------------------------------------------------------------------- 1 | using Besnik.GenericRepository.NHibernate; 2 | using NHibernate.Criterion; 3 | 4 | namespace Besnik.Domain.NHibernateRepository 5 | { 6 | /// 7 | /// Customer specification based on NHibernate criteria queries functionality. 8 | /// 9 | public class CriteriaCustomerSpecification : CriteriaSpecification, ICustomerSpecification 10 | { 11 | public ICustomerSpecification WithName(string name) 12 | { 13 | this.Criteria.Add(Expression.Eq("Name", name)); 14 | return this; 15 | } 16 | 17 | public ICustomerSpecification WithAge(int age) 18 | { 19 | this.Criteria.Add(Expression.Eq("Age", age)); 20 | return this; 21 | } 22 | } 23 | } 24 | -------------------------------------------------------------------------------- /Besnik.Domain.NHibernate/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Besnik.Domain/Besnik.Domain.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.30729 7 | 2.0 8 | {D5B52DDB-C986-4055-9CAC-5526F42B8A93} 9 | Library 10 | Properties 11 | Besnik.Domain 12 | Besnik.Domain 13 | v4.0 14 | 512 15 | 16 | 17 | 3.5 18 | 19 | publish\ 20 | true 21 | Disk 22 | false 23 | Foreground 24 | 7 25 | Days 26 | false 27 | false 28 | true 29 | 0 30 | 1.0.0.%2a 31 | false 32 | false 33 | true 34 | 35 | 36 | 37 | true 38 | full 39 | false 40 | bin\Debug\ 41 | DEBUG;TRACE 42 | prompt 43 | 4 44 | AllRules.ruleset 45 | false 46 | 47 | 48 | 49 | 50 | pdbonly 51 | true 52 | bin\Release\ 53 | TRACE 54 | prompt 55 | 4 56 | AllRules.ruleset 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | {1C33F903-59B8-437C-8637-94CB394CA970} 68 | Besnik.GenericRepository 69 | 70 | 71 | 72 | 73 | False 74 | .NET Framework 3.5 SP1 Client Profile 75 | false 76 | 77 | 78 | False 79 | .NET Framework 3.5 SP1 80 | true 81 | 82 | 83 | False 84 | Windows Installer 3.1 85 | true 86 | 87 | 88 | 89 | 96 | -------------------------------------------------------------------------------- /Besnik.Domain/Entities/Customer.cs: -------------------------------------------------------------------------------- 1 | namespace Besnik.Domain 2 | { 3 | public class Customer 4 | { 5 | public virtual int Id { get; set; } 6 | public virtual string Name { get; set; } 7 | public virtual int Age { get; set; } 8 | } 9 | } 10 | -------------------------------------------------------------------------------- /Besnik.Domain/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Besnik.Domain")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("")] 13 | [assembly: AssemblyCopyright("")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("9492c71f-1ece-4723-ab06-588a7ce4401f")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.1.0.*")] 36 | [assembly: AssemblyFileVersion("1.1.0.0")] 37 | -------------------------------------------------------------------------------- /Besnik.Domain/Repositories/ICustomerRepository.cs: -------------------------------------------------------------------------------- 1 | using Besnik.GenericRepository; 2 | 3 | namespace Besnik.Domain 4 | { 5 | public interface ICustomerRepository : IGenericRepository 6 | { 7 | } 8 | } 9 | -------------------------------------------------------------------------------- /Besnik.Domain/Specifications/CustomerQueryableSpecification.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using Besnik.GenericRepository; 4 | 5 | namespace Besnik.Domain 6 | { 7 | /// 8 | /// Generic specification based on IQueryable interface. 9 | /// 10 | public class CustomerQueryableSpecification 11 | : QueryableSpecification 12 | , ICustomerSpecification 13 | { 14 | /// 15 | /// Constructor. 16 | /// 17 | public CustomerQueryableSpecification(IUnitOfWorkConvertor unitOfWorkConvertor) 18 | : base(unitOfWorkConvertor) 19 | { 20 | } 21 | 22 | /// 23 | /// Specifies the name the query will filter entities for. 24 | /// 25 | public ICustomerSpecification WithName(string name) 26 | { 27 | this.Queryable = this.Queryable.Where(c => c.Name == name); 28 | return this; 29 | } 30 | 31 | /// 32 | /// Specifies the age the query will filter entities for. 33 | /// 34 | public ICustomerSpecification WithAge(int age) 35 | { 36 | this.Queryable = this.Queryable.Where(c => c.Age == age); 37 | return this; 38 | } 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /Besnik.Domain/Specifications/ICustomerSpecification.cs: -------------------------------------------------------------------------------- 1 | using Besnik.GenericRepository; 2 | 3 | namespace Besnik.Domain 4 | { 5 | /// 6 | /// Customer specification using fluent interface. 7 | /// 8 | public interface ICustomerSpecification : ISpecification 9 | { 10 | ICustomerSpecification WithName(string name); 11 | ICustomerSpecification WithAge(int age); 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.EntityFramework/Besnik.GenericRepository.EntityFramework.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {5630007D-50C9-4D99-A734-BBE7451B1C3D} 9 | Library 10 | Properties 11 | Besnik.GenericRepository.EntityFramework 12 | Besnik.GenericRepository.EntityFramework 13 | v4.0 14 | 512 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | bin\Debug\Besnik.GenericRepository.EntityFramework.XML 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | bin\Release\Besnik.GenericRepository.EntityFramework.xml 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | ..\packages\EntityFramework.4.3.1\lib\net40\EntityFramework.dll 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | {1C33F903-59B8-437C-8637-94CB394CA970} 55 | Besnik.GenericRepository 56 | 57 | 58 | 59 | 60 | 61 | 62 | 69 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.EntityFramework/EntityFrameworkTransaction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Transactions; 3 | 4 | namespace Besnik.GenericRepository.EntityFramework 5 | { 6 | /// 7 | /// Entity framework implementation of the transaction. 8 | /// 9 | public class EntityFrameworkTransaction : ITransaction 10 | { 11 | public EntityFrameworkTransaction(EntityFrameworkUnitOfWork unitOfWork) 12 | { 13 | this.UnitOfWork = unitOfWork; 14 | this.TransactionScope = new TransactionScope(); 15 | } 16 | 17 | protected EntityFrameworkUnitOfWork UnitOfWork { get; private set; } 18 | 19 | protected TransactionScope TransactionScope { get; private set; } 20 | 21 | /// 22 | /// Flushes unit of work and commits the transaction scope. 23 | /// 24 | public void Commit() 25 | { 26 | this.UnitOfWork.Flush(); 27 | this.TransactionScope.Complete(); 28 | } 29 | 30 | /// 31 | /// Rolls back transaction. 32 | /// Actually the transaction rollback is handled automatically with Dispose method if 33 | /// transaction scope was not commited. 34 | /// 35 | public void Rollback() 36 | { 37 | } 38 | 39 | public void Dispose() 40 | { 41 | if (this.TransactionScope != null) 42 | { 43 | (this.TransactionScope as IDisposable).Dispose(); 44 | this.TransactionScope = null; 45 | this.UnitOfWork = null; 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.EntityFramework/EntityFrameworkUnitOfWork.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | using System.Collections.Generic; 4 | using System.Data.Entity; 5 | 6 | namespace Besnik.GenericRepository.EntityFramework 7 | { 8 | public class EntityFrameworkUnitOfWork : IUnitOfWork 9 | { 10 | public EntityFrameworkUnitOfWork(DbContext dbContext) 11 | { 12 | this.DbContext = dbContext; 13 | } 14 | 15 | public DbContext DbContext { get; protected set; } 16 | 17 | public void Flush() 18 | { 19 | this.DbContext.SaveChanges(); 20 | } 21 | 22 | public ITransaction BeginTransaction() 23 | { 24 | return new EntityFrameworkTransaction(this); 25 | } 26 | 27 | public void EndTransaction(ITransaction transaction) 28 | { 29 | if (transaction != null) 30 | { 31 | (transaction as IDisposable).Dispose(); 32 | transaction = null; 33 | } 34 | } 35 | 36 | public void Insert(TEntity entity) where TEntity : class 37 | { 38 | this.DbContext.Set().Add(entity); 39 | } 40 | 41 | public void Update(TEntity entity) where TEntity : class 42 | { 43 | this.DbContext.Set().Attach(entity); 44 | } 45 | 46 | public void Delete(TEntity entity) where TEntity : class 47 | { 48 | this.DbContext.Set().Remove(entity); 49 | } 50 | 51 | public TEntity GetById(TPrimaryKey id) where TEntity : class 52 | { 53 | return this.DbContext.Set().Find(id); 54 | } 55 | 56 | public IList GetAll() where TEntity : class 57 | { 58 | return this.DbContext.Set().ToList(); 59 | } 60 | 61 | public void Dispose() 62 | { 63 | if (this.DbContext != null) 64 | { 65 | this.DbContext.SaveChanges(); 66 | (this.DbContext as IDisposable).Dispose(); 67 | this.DbContext = null; 68 | } 69 | } 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.EntityFramework/EntityFrameworkUnitOfWorkConvertor.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | 3 | namespace Besnik.GenericRepository.EntityFramework 4 | { 5 | /// 6 | /// Helper class to convert Entity Framework DbContext to various data providers. 7 | /// 8 | public class EntityFrameworkUnitOfWorkConvertor : IUnitOfWorkConvertor 9 | { 10 | /// 11 | /// Gets from wrapped 12 | /// in the given instance. 13 | /// 14 | public IQueryable ToQueryable(IUnitOfWork unitOfWork) where TEntity : class 15 | { 16 | return (unitOfWork as EntityFrameworkUnitOfWork).DbContext.Set(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.EntityFramework/EntityFrameworkUnitOfWorkFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data.Entity; 3 | using System.Data.Entity.Infrastructure; 4 | 5 | namespace Besnik.GenericRepository.EntityFramework 6 | { 7 | /// 8 | /// Unit of work factory implementation for Entity Framework. 9 | /// Note: implementation based on extension Feature CTP4. 10 | /// 11 | public class EntityFrameworkUnitOfWorkFactory : IUnitOfWorkFactory 12 | { 13 | public EntityFrameworkUnitOfWorkFactory(string connectionString, DbModel dbModel) 14 | { 15 | this.ConnectionString = connectionString; 16 | this.DbModel = dbModel; 17 | } 18 | 19 | protected string ConnectionString { get; private set; } 20 | 21 | protected DbModel DbModel { get; private set; } 22 | 23 | public IUnitOfWork BeginUnitOfWork() 24 | { 25 | return new EntityFrameworkUnitOfWork( 26 | this.CreateDbContext() 27 | ); 28 | } 29 | 30 | private DbContext CreateDbContext() 31 | { 32 | return new DbContext( 33 | this.ConnectionString 34 | , this.DbModel.Compile() 35 | ); 36 | } 37 | 38 | public void EndUnitOfWork(IUnitOfWork unitOfWork) 39 | { 40 | var linqToSqlUnitOfWork = unitOfWork as EntityFrameworkUnitOfWork; 41 | if (linqToSqlUnitOfWork != null) 42 | { 43 | linqToSqlUnitOfWork.Dispose(); 44 | linqToSqlUnitOfWork = null; 45 | } 46 | } 47 | 48 | public void Dispose() 49 | { 50 | this.ConnectionString = null; 51 | this.DbModel = null; 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.EntityFramework/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Besnik.GenericRepository.EntityFramework")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("")] 13 | [assembly: AssemblyCopyright("")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("add9812d-bfab-4e6e-ac47-3161b02f8c9c")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.1.0.*")] 36 | [assembly: AssemblyFileVersion("1.1.0.0")] 37 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.EntityFramework/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.LinqToSql/Besnik.GenericRepository.LinqToSql.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {207ADEBC-CCE9-4ACC-AEA8-E086BB23A638} 9 | Library 10 | Properties 11 | Besnik.GenericRepository.LinqToSql 12 | Besnik.GenericRepository.LinqToSql 13 | v4.0 14 | 512 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | bin\Debug\Besnik.GenericRepository.LinqToSql.xml 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | bin\Release\Besnik.GenericRepository.LinqToSql.xml 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | {1C33F903-59B8-437C-8637-94CB394CA970} 46 | Besnik.GenericRepository 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 63 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.LinqToSql/LinqToSqlRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data.Linq; 3 | using System.Linq; 4 | using System.Linq.Expressions; 5 | 6 | namespace Besnik.GenericRepository.LinqToSql 7 | { 8 | /// 9 | /// Base class for repositories based on LinqToSql technology. 10 | /// 11 | /// 12 | /// As the LinqToSql does not support general mechanism to get entity by id, 13 | /// we must extend base to add this functionality. 14 | /// It is done via predicate that specifies id of the entity. 15 | /// 16 | public abstract class LinqToSqlRepository 17 | : GenericRepository 18 | where TEntity : class 19 | { 20 | /// 21 | /// Constructor. 22 | /// 23 | public LinqToSqlRepository(IUnitOfWork unitOfWork, ISpecificationLocator specificationLocator) 24 | : base(unitOfWork, specificationLocator) 25 | { 26 | } 27 | 28 | /// 29 | /// Gets table of entities for the unit of work. 30 | /// 31 | protected Table Table 32 | { 33 | get 34 | { 35 | return ( this.UnitOfWork as LinqToSqlUnitOfWork ).DataContext.GetTable(); 36 | } 37 | } 38 | 39 | /// 40 | /// Specifies predicate for method. 41 | /// 42 | protected abstract Expression> FirstOrDefaultPredicate(TPrimaryKey id); 43 | 44 | /// 45 | /// Gets entity by it's Id. 46 | /// 47 | /// 48 | /// The functionality has to be explicitely implemented here since we need concrete 49 | /// predicate for TEntity to select entity. 50 | /// 51 | public override TEntity GetById(TPrimaryKey id) 52 | { 53 | return this.Table.FirstOrDefault(FirstOrDefaultPredicate(id)); 54 | } 55 | 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.LinqToSql/LinqToSqlTransaction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Transactions; 3 | 4 | namespace Besnik.GenericRepository.LinqToSql 5 | { 6 | /// 7 | /// LINQ to SQL implementation of transaction. 8 | /// 9 | public class LinqToSqlTransaction : ITransaction 10 | { 11 | public LinqToSqlTransaction(LinqToSqlUnitOfWork unitOfWork) 12 | { 13 | this.UnitOfWork = unitOfWork; 14 | this.TransactionScope = new TransactionScope(); 15 | } 16 | 17 | protected LinqToSqlUnitOfWork UnitOfWork { get; private set; } 18 | 19 | protected TransactionScope TransactionScope { get; private set; } 20 | 21 | #region ITransaction Members 22 | 23 | /// 24 | /// Flushes unit of work and commits the transaction scope. 25 | /// 26 | public void Commit() 27 | { 28 | this.UnitOfWork.Flush(); 29 | this.TransactionScope.Complete(); 30 | } 31 | 32 | /// 33 | /// Rolls back transaction. 34 | /// Actually the transaction rollback is handled automatically with Dispose method if 35 | /// transaction scope was not commited. 36 | /// 37 | public void Rollback() 38 | { 39 | } 40 | 41 | #endregion 42 | 43 | #region IDisposable Members 44 | 45 | public void Dispose() 46 | { 47 | if ( this.TransactionScope != null ) 48 | { 49 | (this.TransactionScope as IDisposable).Dispose(); 50 | this.TransactionScope = null; 51 | this.UnitOfWork = null; 52 | } 53 | } 54 | 55 | #endregion 56 | } 57 | } 58 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.LinqToSql/LinqToSqlUnitOfWork.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Data.Linq; 4 | using System.Linq; 5 | 6 | namespace Besnik.GenericRepository.LinqToSql 7 | { 8 | public class LinqToSqlUnitOfWork : IUnitOfWork 9 | { 10 | public LinqToSqlUnitOfWork(DataContext dataContext) 11 | { 12 | this.DataContext = dataContext; 13 | } 14 | 15 | public DataContext DataContext { get; private set; } 16 | 17 | protected Table GetTable() where TEntity : class 18 | { 19 | return this.DataContext.GetTable(); 20 | } 21 | 22 | #region IUnitOfWork Members 23 | 24 | public void Flush() 25 | { 26 | this.DataContext.SubmitChanges(); 27 | } 28 | 29 | public ITransaction BeginTransaction() 30 | { 31 | return new LinqToSqlTransaction(this); 32 | } 33 | 34 | public void EndTransaction(ITransaction transaction) 35 | { 36 | if (transaction != null) 37 | { 38 | (transaction as IDisposable).Dispose(); 39 | transaction = null; 40 | } 41 | } 42 | 43 | public void Insert(TEntity entity) where TEntity : class 44 | { 45 | this.GetTable().InsertOnSubmit(entity); 46 | } 47 | 48 | public void Update(TEntity entity) where TEntity : class 49 | { 50 | // Attach with "true" to say this is a modified entity 51 | // and it can be checked for optimistic concurrency because 52 | // it has a column that is marked with "RowVersion" attribute 53 | this.GetTable().Attach(entity, true); 54 | } 55 | 56 | public void Delete(TEntity entity) where TEntity : class 57 | { 58 | this.GetTable().DeleteOnSubmit(entity); 59 | } 60 | 61 | public TEntity GetById(TPrimaryKey id) where TEntity : class 62 | { 63 | // Unit of work can not support this since LinqToSql implementation is 64 | // based on Linq FirstOrDefault functionality that expects predicate 65 | // and here the details of TEntity are unknown. 66 | // The functionality is implemented directly in the LinqToSqlRepository type. 67 | throw new NotImplementedException("Implement directly in repository."); 68 | } 69 | 70 | public IList GetAll() where TEntity : class 71 | { 72 | return this.GetTable().ToList(); 73 | 74 | } 75 | 76 | #endregion 77 | 78 | #region IDisposable Members 79 | 80 | public void Dispose() 81 | { 82 | if ( this.DataContext != null ) 83 | { 84 | this.DataContext.SubmitChanges(); 85 | (this.DataContext as IDisposable).Dispose(); 86 | this.DataContext = null; 87 | } 88 | } 89 | 90 | #endregion 91 | 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.LinqToSql/LinqToSqlUnitOfWorkConvertor.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | 3 | namespace Besnik.GenericRepository.LinqToSql 4 | { 5 | /// 6 | /// Helper class to convert LinqToSql DataContext to various data providers. 7 | /// 8 | public class LinqToSqlUnitOfWorkConvertor : IUnitOfWorkConvertor 9 | { 10 | /// 11 | /// Gets from wrapped 12 | /// in the given instance. 13 | /// 14 | public IQueryable ToQueryable(IUnitOfWork unitOfWork) where TEntity : class 15 | { 16 | return (unitOfWork as LinqToSqlUnitOfWork).DataContext.GetTable(); 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.LinqToSql/LinqToSqlUnitOfWorkFactory.cs: -------------------------------------------------------------------------------- 1 | using System.Data.Linq; 2 | using System.Data.Linq.Mapping; 3 | 4 | namespace Besnik.GenericRepository.LinqToSql 5 | { 6 | public class LinqToSqlUnitOfWorkFactory : IUnitOfWorkFactory 7 | { 8 | public LinqToSqlUnitOfWorkFactory(string connectionString, MappingSource mapping) 9 | { 10 | this.ConnectionString = connectionString; 11 | this.Mapping = mapping; 12 | } 13 | 14 | protected string ConnectionString { get; private set; } 15 | 16 | protected MappingSource Mapping { get; private set; } 17 | 18 | protected DataContext CreateDataContext() 19 | { 20 | return new DataContext( 21 | this.ConnectionString 22 | , this.Mapping 23 | ); 24 | } 25 | 26 | public IUnitOfWork BeginUnitOfWork() 27 | { 28 | return new LinqToSqlUnitOfWork( 29 | this.CreateDataContext() 30 | ); 31 | } 32 | 33 | public void EndUnitOfWork(IUnitOfWork unitOfWork) 34 | { 35 | var linqToSqlUnitOfWork = unitOfWork as LinqToSqlUnitOfWork; 36 | if ( linqToSqlUnitOfWork != null ) 37 | { 38 | linqToSqlUnitOfWork.Dispose(); 39 | linqToSqlUnitOfWork = null; 40 | } 41 | } 42 | 43 | public void Dispose() 44 | { 45 | this.ConnectionString = null; 46 | this.Mapping = null; 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.LinqToSql/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Besnik.GenericRepository.LinqToSql")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("")] 13 | [assembly: AssemblyCopyright("")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("f4d15c9a-cd1d-4432-865b-7ed993e6fce5")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.1.0.*")] 36 | [assembly: AssemblyFileVersion("1.1.0.0")] 37 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.NHibernate/Besnik.GenericRepository.NHibernate.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 8.0.30703 7 | 2.0 8 | {DCC5973E-B6BC-4A41-8996-ED4AFBEEB318} 9 | Library 10 | Properties 11 | Besnik.GenericRepository.NHibernate 12 | Besnik.GenericRepository.NHibernate 13 | v4.0 14 | 512 15 | 16 | 17 | true 18 | full 19 | false 20 | bin\Debug\ 21 | DEBUG;TRACE 22 | prompt 23 | 4 24 | bin\Debug\Besnik.GenericRepository.NHibernate.xml 25 | 26 | 27 | pdbonly 28 | true 29 | bin\Release\ 30 | TRACE 31 | prompt 32 | 4 33 | bin\Release\Besnik.GenericRepository.NHibernate.xml 34 | 35 | 36 | 37 | ..\packages\Iesi.Collections.3.2.0.4000\lib\Net35\Iesi.Collections.dll 38 | 39 | 40 | False 41 | ..\packages\NHibernate.3.3.0.4000\lib\Net35\NHibernate.dll 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | {1C33F903-59B8-437C-8637-94CB394CA970} 57 | Besnik.GenericRepository 58 | 59 | 60 | 61 | 62 | 63 | 64 | 71 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.NHibernate/NHibernateTransaction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using INHibernateTransaction = global::NHibernate.ITransaction; 3 | 4 | namespace Besnik.GenericRepository.NHibernate 5 | { 6 | /// 7 | /// NHibernate implementation of transaction. 8 | /// 9 | public class NHibernateTransaction : GenericRepository.ITransaction 10 | { 11 | public NHibernateTransaction(INHibernateTransaction transaction) 12 | { 13 | this.Transaction = transaction; 14 | } 15 | 16 | protected INHibernateTransaction Transaction { get; private set; } 17 | 18 | public void Commit() 19 | { 20 | this.Transaction.Commit(); 21 | } 22 | 23 | public void Rollback() 24 | { 25 | this.Transaction.Rollback(); 26 | } 27 | 28 | public void Dispose() 29 | { 30 | if ( this.Transaction != null ) 31 | { 32 | (this.Transaction as IDisposable).Dispose(); 33 | this.Transaction = null; 34 | } 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.NHibernate/NHibernateUnitOfWork.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using NHibernate; 4 | 5 | namespace Besnik.GenericRepository.NHibernate 6 | { 7 | public class NHibernateUnitOfWork : IUnitOfWork 8 | { 9 | public NHibernateUnitOfWork(ISession session) 10 | { 11 | this.Session = session; 12 | } 13 | 14 | public ISession Session { get; private set; } 15 | 16 | #region IUnitOfWork Members 17 | 18 | public void Flush() 19 | { 20 | this.Session.Flush(); 21 | } 22 | 23 | public GenericRepository.ITransaction BeginTransaction() 24 | { 25 | return new NHibernateTransaction( 26 | this.Session.BeginTransaction() 27 | ); 28 | } 29 | 30 | public void EndTransaction(GenericRepository.ITransaction transaction) 31 | { 32 | if (transaction != null) 33 | { 34 | (transaction as IDisposable).Dispose(); 35 | transaction = null; 36 | } 37 | } 38 | 39 | public void Insert(TEntity entity) where TEntity : class 40 | { 41 | this.Session.Save(entity); 42 | } 43 | 44 | public void Update(TEntity entity) where TEntity : class 45 | { 46 | this.Session.Update(entity); 47 | } 48 | 49 | public void Delete(TEntity entity) where TEntity : class 50 | { 51 | this.Session.Delete(entity); 52 | } 53 | 54 | public TEntity GetById(TPrimaryKey id) where TEntity : class 55 | { 56 | return this.Session.Get(id); 57 | } 58 | 59 | public IList GetAll() where TEntity : class 60 | { 61 | return this.Session.CreateCriteria().List(); 62 | } 63 | 64 | #endregion 65 | 66 | #region IDisposable Members 67 | 68 | public void Dispose() 69 | { 70 | if ( this.Session != null ) 71 | { 72 | (this.Session as IDisposable).Dispose(); 73 | this.Session = null; 74 | } 75 | } 76 | 77 | #endregion 78 | 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.NHibernate/NHibernateUnitOfWorkConvertor.cs: -------------------------------------------------------------------------------- 1 | using System.Linq; 2 | using NHibernate.Linq; 3 | 4 | namespace Besnik.GenericRepository.NHibernate 5 | { 6 | /// 7 | /// Helper class to convert NHibernate ISession to various data providers. 8 | /// 9 | public class NHibernateUnitOfWorkConvertor : IUnitOfWorkConvertor 10 | { 11 | /// 12 | /// Gets from wrapped 13 | /// in the given instance. 14 | /// 15 | public IQueryable ToQueryable(IUnitOfWork unitOfWork) where TEntity : class 16 | { 17 | return (unitOfWork as NHibernateUnitOfWork).Session.Query(); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.NHibernate/NHibernateUnitOfWorkFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Reflection; 3 | using NHibernate; 4 | using NHibernate.Cfg; 5 | using NHibernate.Tool.hbm2ddl; 6 | 7 | namespace Besnik.GenericRepository.NHibernate 8 | { 9 | public class NHibernateUnitOfWorkFactory : IUnitOfWorkFactory 10 | { 11 | public NHibernateUnitOfWorkFactory(string nhibernateConfigPath, Assembly assembly) 12 | { 13 | var cfg = new Configuration(); 14 | 15 | try 16 | { 17 | // configuration is immutable, store last returned value 18 | cfg.Configure(nhibernateConfigPath); 19 | Configuration = cfg.AddAssembly(assembly); 20 | } 21 | catch ( Exception ex ) 22 | { 23 | throw new GenericRepositoryException( 24 | string.Format("Error while configuring NHibernate: {0}.", ex.Message) 25 | , ex 26 | ); 27 | } 28 | 29 | try 30 | { 31 | SessionFactory = Configuration.BuildSessionFactory(); 32 | } 33 | catch ( Exception ex ) 34 | { 35 | throw new GenericRepositoryException( 36 | string.Format("Error while building NH session factory: {0}.", ex.Message) 37 | , ex 38 | ); 39 | } 40 | } 41 | 42 | protected ISessionFactory SessionFactory { get; private set; } 43 | 44 | protected Configuration Configuration { get; private set; } 45 | 46 | /// 47 | /// Generates table structure inside specified database. 48 | /// 49 | public void NHibernateSchemaExport() 50 | { 51 | new SchemaExport(this.Configuration).Execute(false, true, false); 52 | } 53 | 54 | #region IUnitOfWorkFactory Members 55 | 56 | public IUnitOfWork BeginUnitOfWork() 57 | { 58 | return new NHibernateUnitOfWork( this.SessionFactory.OpenSession() ); 59 | } 60 | 61 | public void EndUnitOfWork(IUnitOfWork unitOfWork) 62 | { 63 | var nhUnitOfWork = unitOfWork as NHibernateUnitOfWork; 64 | if ( unitOfWork != null ) 65 | { 66 | unitOfWork.Dispose(); 67 | unitOfWork = null; 68 | } 69 | } 70 | 71 | #endregion 72 | 73 | #region IDisposable Members 74 | 75 | public void Dispose() 76 | { 77 | if ( this.SessionFactory != null ) 78 | { 79 | (this.SessionFactory as IDisposable).Dispose(); 80 | this.SessionFactory = null; 81 | this.Configuration = null; 82 | } 83 | } 84 | 85 | #endregion 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.NHibernate/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Besnik.GenericRepository.NHibernate")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("")] 13 | [assembly: AssemblyCopyright("")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("b0f204d5-cb67-4a7c-a67d-504e126ef3c2")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.1.0.*")] 36 | [assembly: AssemblyFileVersion("1.1.0.0")] 37 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.NHibernate/Specifications/CriteriaSpecification.cs: -------------------------------------------------------------------------------- 1 | using NHibernate; 2 | 3 | namespace Besnik.GenericRepository.NHibernate 4 | { 5 | public abstract class CriteriaSpecification : ISpecification where TEntity : class 6 | { 7 | /// 8 | /// Gets criteria specification. 9 | /// 10 | protected ICriteria Criteria { get; private set; } 11 | 12 | /// 13 | /// Initializes criteria for the specification. 14 | /// 15 | public void Initialize(IUnitOfWork unitOfWork) 16 | { 17 | this.Criteria = (unitOfWork as NHibernateUnitOfWork).Session.CreateCriteria(); 18 | } 19 | 20 | /// 21 | /// Gets . 22 | /// 23 | /// 24 | public ISpecificationResult ToResult() 25 | { 26 | return new CriteriaSpecificationResult(this.Criteria); 27 | } 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.NHibernate/Specifications/CriteriaSpecificationResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq.Expressions; 4 | using NHibernate; 5 | using NHibernate.Criterion; 6 | 7 | namespace Besnik.GenericRepository.NHibernate 8 | { 9 | /// 10 | /// The class represents criteria specification result with 11 | /// generic functionality for all specifications. 12 | /// 13 | public class CriteriaSpecificationResult : ISpecificationResult 14 | where TEntity : class 15 | { 16 | /// 17 | /// Constructor. 18 | /// 19 | public CriteriaSpecificationResult(ICriteria criteria) 20 | { 21 | this.Criteria = criteria; 22 | } 23 | 24 | /// 25 | /// Gets criteria specification. 26 | /// 27 | protected ICriteria Criteria { get; private set; } 28 | 29 | /// 30 | /// Takes only given amount of entities. 31 | /// 32 | public ISpecificationResult Take(int count) 33 | { 34 | this.Criteria.SetMaxResults(count); 35 | return this; 36 | } 37 | 38 | /// 39 | /// Gets list of entities represented by the specification. 40 | /// 41 | public IList ToList() 42 | { 43 | return this.Criteria.List(); 44 | } 45 | 46 | /// 47 | /// Gets single result represented by the specification. 48 | /// 49 | public TEntity Single() 50 | { 51 | var result = this.Criteria.UniqueResult(); 52 | 53 | if (result == null) 54 | { 55 | throw new InvalidOperationException("The input sequence is empty."); 56 | } 57 | 58 | return result; 59 | } 60 | 61 | /// 62 | /// Skips given number of entities when returning the result. 63 | /// 64 | public ISpecificationResult Skip(int count) 65 | { 66 | this.Criteria.SetFirstResult(count); 67 | return this; 68 | } 69 | 70 | /// 71 | /// Validates given body of the expression for ordering functionality. 72 | /// The client has to specify a property or field of the entity by which 73 | /// the ordering shall happen. 74 | /// 75 | private void ValidateForMemberExpression(System.Linq.Expressions.Expression expression) 76 | { 77 | if (! (expression is MemberExpression) ) 78 | { 79 | throw new GenericRepositoryException("A property of the entity needs to be specified."); 80 | } 81 | } 82 | 83 | /// 84 | /// Orders specified entities by given key in ascending order. 85 | /// 86 | public ISpecificationResult OrderByAscending( 87 | System.Linq.Expressions.Expression> keySelector 88 | ) 89 | { 90 | ValidateForMemberExpression(keySelector.Body); 91 | 92 | var propertyName = (keySelector.Body as MemberExpression).Member.Name; 93 | this.Criteria.AddOrder( Order.Asc(propertyName) ); 94 | return this; 95 | } 96 | 97 | /// 98 | /// Orders specified entities by given key in descending order. 99 | /// 100 | public ISpecificationResult OrderByDescending( 101 | System.Linq.Expressions.Expression> keySelector 102 | ) 103 | { 104 | ValidateForMemberExpression(keySelector.Body); 105 | 106 | var propertyName = (keySelector.Body as MemberExpression).Member.Name; 107 | this.Criteria.AddOrder( Order.Desc(propertyName) ); 108 | return this; 109 | } 110 | 111 | /// 112 | /// Returns the only element of a sequence, or a default value if the sequence is empty; 113 | /// this method throws an exception if there is more than one element in the sequence. 114 | /// 115 | public TEntity SingleOrDefault() 116 | { 117 | return this.Criteria.UniqueResult(); 118 | } 119 | } 120 | } 121 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.NHibernate/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.Tests/Besnik.GenericRepository.Tests.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.30729 7 | 2.0 8 | {1AA5D032-863A-4952-A00A-E48475E9CB9D} 9 | Library 10 | Properties 11 | Besnik.GenericRepository.Tests 12 | Besnik.GenericRepository.Tests 13 | v4.0 14 | 512 15 | 16 | 17 | 3.5 18 | 19 | publish\ 20 | true 21 | Disk 22 | false 23 | Foreground 24 | 7 25 | Days 26 | false 27 | false 28 | true 29 | 0 30 | 1.0.0.%2a 31 | false 32 | false 33 | true 34 | 35 | 36 | 37 | true 38 | full 39 | false 40 | bin\Debug\ 41 | DEBUG;TRACE 42 | prompt 43 | 4 44 | AllRules.ruleset 45 | 46 | 47 | 48 | 49 | pdbonly 50 | true 51 | bin\Release\ 52 | TRACE 53 | prompt 54 | 4 55 | AllRules.ruleset 56 | 57 | 58 | 59 | ..\packages\Autofac.2.6.1.841\lib\NET40\Autofac.dll 60 | 61 | 62 | ..\packages\Autofac.2.6.1.841\lib\NET40\Autofac.Configuration.dll 63 | 64 | 65 | ..\packages\EntityFramework.4.3.1\lib\net40\EntityFramework.dll 66 | 67 | 68 | ..\packages\Iesi.Collections.3.2.0.4000\lib\Net35\Iesi.Collections.dll 69 | 70 | 71 | ..\packages\log4net.2.0.0\lib\net40-full\log4net.dll 72 | 73 | 74 | False 75 | ..\packages\NHibernate.3.3.0.4000\lib\Net35\NHibernate.dll 76 | 77 | 78 | ..\packages\NHibernate.Linq.1.0\lib\NHibernate.Linq.dll 79 | 80 | 81 | False 82 | ..\packages\NUnit.2.6.0.12054\lib\nunit.framework.dll 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | ..\packages\System.Data.SQLite.1.0.80.0\lib\net40\System.Data.SQLite.dll 92 | 93 | 94 | ..\packages\System.Data.SQLite.1.0.80.0\lib\net40\System.Data.SQLite.Linq.dll 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | {B3288165-24F4-49AF-A7B5-79B027F82EC8} 112 | Besnik.Domain.EntityFramework 113 | 114 | 115 | {D5B52DDB-C986-4055-9CAC-5526F42B8A93} 116 | Besnik.Domain 117 | 118 | 119 | {5630007D-50C9-4D99-A734-BBE7451B1C3D} 120 | Besnik.GenericRepository.EntityFramework 121 | 122 | 123 | {207ADEBC-CCE9-4ACC-AEA8-E086BB23A638} 124 | Besnik.GenericRepository.LinqToSql 125 | 126 | 127 | {DCC5973E-B6BC-4A41-8996-ED4AFBEEB318} 128 | Besnik.GenericRepository.NHibernate 129 | 130 | 131 | {1C33F903-59B8-437C-8637-94CB394CA970} 132 | Besnik.GenericRepository 133 | 134 | 135 | {C6CC3E66-9506-43D7-BE8F-0C49D59C34E3} 136 | Besnik.Domain.LinqToSqlRepository 137 | 138 | 139 | {ABDD5544-3CAA-49FB-A06A-895585BA55B2} 140 | Besnik.Domain.NHibernateRepository 141 | 142 | 143 | 144 | 145 | 146 | PreserveNewest 147 | 148 | 149 | 150 | PreserveNewest 151 | 152 | 153 | 154 | 155 | 156 | False 157 | .NET Framework 3.5 SP1 Client Profile 158 | false 159 | 160 | 161 | False 162 | .NET Framework 3.5 SP1 163 | true 164 | 165 | 166 | False 167 | Windows Installer 3.1 168 | true 169 | 170 | 171 | 172 | 179 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.Tests/Besnik.GenericRepository.Tests.nunit: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.Tests/Config/App.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 8 | 11 | 12 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.Tests/Config/NHibernate.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | NHibernate.Connection.DriverConnectionProvider 6 | NHibernate.Dialect.MsSql2005Dialect 7 | NHibernate.Driver.SqlClientDriver 8 | Data Source=BESNIK\SQLEXPRESS;Initial Catalog=Besnik.GenericRepository.NHibernate;Integrated Security=True 9 | 10 | true 11 | 12 | 13 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.Tests/Config/NHibernate.sqlite.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | NHibernate.Driver.SQLite20Driver 6 | 7 | Data Source=genericrepository.db;Version=3 8 | 9 | NHibernate.Dialect.SQLiteDialect 10 | true=1;false=0 11 | 12 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.Tests/Factory/Factory.cs: -------------------------------------------------------------------------------- 1 | using Autofac; 2 | using Besnik.Domain; 3 | using Besnik.GenericRepository; 4 | using System; 5 | using Besnik.GenericRepository.NHibernate; 6 | using Besnik.GenericRepository.LinqToSql; 7 | using Besnik.Domain.NHibernateRepository; 8 | using Besnik.GenericRepository.EntityFramework; 9 | 10 | namespace Besnik.GenericRepository.Tests 11 | { 12 | public class Factory 13 | { 14 | public static readonly string DefaultCustomerName = "John Doe"; 15 | public static readonly int DefaultCustomerAge = 16; 16 | public static readonly string NHibernateConfigPath = "Config\\NHibernate.config"; 17 | 18 | /// 19 | /// Gets customer stub. 20 | /// 21 | public Customer GetCustomer() 22 | { 23 | return GetCustomer(DefaultCustomerName, DefaultCustomerAge); 24 | } 25 | 26 | /// 27 | /// Gets customer stub with given name and age. 28 | /// 29 | public Customer GetCustomer(string name, int age) 30 | { 31 | return new Customer() 32 | { 33 | Name = name, 34 | Age = age 35 | }; 36 | } 37 | 38 | public IUnitOfWorkConvertor GetNHibernateUnitOfWorkConvertor() 39 | { 40 | return new NHibernateUnitOfWorkConvertor(); 41 | } 42 | 43 | public IUnitOfWorkConvertor GetLinqToSqlUnitOfWorkConvertor() 44 | { 45 | return new LinqToSqlUnitOfWorkConvertor(); 46 | } 47 | 48 | /// 49 | /// Generic method that gets specification locator stub prepared for queryable 50 | /// ICustomerSpecification. Use input type param to specify specification factory for 51 | /// concrete unit of work implementation that converts unit of work to specification. 52 | /// 53 | protected ISpecificationLocator GetSpecificationLocator(Action action) 54 | { 55 | // ioc container 56 | var builder = new ContainerBuilder(); 57 | 58 | builder.RegisterType() 59 | .As() 60 | .InstancePerDependency(); 61 | 62 | action(builder); 63 | 64 | var container = builder.Build(); 65 | 66 | // specification locator 67 | var specificationLocator = new SpecificationLocatorStub(container); 68 | 69 | return specificationLocator; 70 | } 71 | 72 | public ISpecificationLocator GetSpecificationLocatorForLinqToSql() 73 | { 74 | return GetSpecificationLocator( 75 | b => 76 | { 77 | b.RegisterType() 78 | .As() 79 | .SingleInstance(); 80 | }); 81 | } 82 | 83 | public ISpecificationLocator GetSpecificationLocatorForEntityFramework() 84 | { 85 | return GetSpecificationLocator( 86 | b => 87 | { 88 | b.RegisterType() 89 | .As() 90 | .SingleInstance(); 91 | }); 92 | } 93 | 94 | public ISpecificationLocator GetSpecificationLocatorForNHibernate() 95 | { 96 | return GetSpecificationLocator( 97 | b => 98 | { 99 | b.RegisterType() 100 | .As() 101 | .SingleInstance(); 102 | }); 103 | } 104 | 105 | public ISpecificationLocator GetSpecificationLocatorForNHibernateWithCriteria() 106 | { 107 | return GetSpecificationLocator( 108 | b => 109 | { 110 | b.RegisterType() 111 | .As() 112 | .InstancePerDependency(); 113 | b.RegisterType() 114 | .As() 115 | .SingleInstance(); 116 | }); 117 | } 118 | } 119 | } 120 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.Tests/Fixtures/EntityFrameworkFixtures/EntityFrameworkCustomerRepositoryFixture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NUnit.Framework; 3 | using Besnik.GenericRepository.EntityFramework; 4 | using System.Data.Entity.Infrastructure; 5 | using System.Data.Entity.ModelConfiguration; 6 | using Besnik.Domain.EntityFramework; 7 | using Besnik.Domain; 8 | using System.Data.Entity; 9 | using System.Data; 10 | 11 | namespace Besnik.GenericRepository.Tests 12 | { 13 | [TestFixture] 14 | public class EntityFrameworkCustomerRepositoryFixture : GenericCustomerRepositoryFixture 15 | { 16 | protected override IUnitOfWorkFactory CreateUnitOfWorkFactory() 17 | { 18 | var dbInitializer = new DropCreateDatabaseIfModelChanges(); 19 | Database.SetInitializer(dbInitializer); 20 | 21 | return new EntityFrameworkUnitOfWorkFactory( 22 | this.GetConnectionString() 23 | , this.GetDbModel() 24 | ); 25 | } 26 | 27 | protected override void InitializeDataStorage() 28 | { 29 | using (var uow = this.UnitOfWorkFactory.BeginUnitOfWork()) 30 | { 31 | var dbContext = (uow as EntityFrameworkUnitOfWork).DbContext; 32 | dbContext.Database.Initialize(false); 33 | 34 | // clear db manually as EF 4 Extensions CTP4 does not contain any functionality 35 | // except deleting and creating database which is not what we want. 36 | var connection = dbContext.Database.Connection; 37 | 38 | try 39 | { 40 | connection.Open(); 41 | 42 | using (var dbCommand = connection.CreateCommand()) 43 | { 44 | dbCommand.CommandText = "delete from Customers"; 45 | dbCommand.ExecuteNonQuery(); 46 | } 47 | } 48 | finally 49 | { 50 | connection.Close(); 51 | } 52 | } 53 | } 54 | 55 | protected override ICustomerRepository CreateCustomerRepository(IUnitOfWork unitOfWork) 56 | { 57 | var specificationLocator = this.Factory.GetSpecificationLocatorForEntityFramework(); 58 | return new CustomerRepository(unitOfWork, specificationLocator); 59 | } 60 | 61 | protected override Customer GetCustomer(int customerId, IUnitOfWork unitOfWork) 62 | { 63 | var dbContext = (unitOfWork as EntityFrameworkUnitOfWork).DbContext; 64 | var customerSet = dbContext.Set(); 65 | return customerSet.Find(customerId); 66 | } 67 | 68 | /// 69 | /// Gets key in connection strings section used to load connection string from app.config. 70 | /// 71 | protected virtual string ConnectionStringKey 72 | { 73 | get 74 | { 75 | return "EntityFrameworkConnectionString"; 76 | } 77 | } 78 | 79 | /// 80 | /// Gets connection string from config file used to initialize unit of work factory. 81 | /// 82 | protected virtual string GetConnectionString() 83 | { 84 | return this.Configuration.ConnectionStrings.ConnectionStrings[ConnectionStringKey].ConnectionString; 85 | } 86 | 87 | /// 88 | /// Gets entity framework's db model for the domain model. 89 | /// 90 | /// 91 | protected virtual DbModel GetDbModel() 92 | { 93 | var modelBuilder = new DbModelBuilder(); 94 | 95 | modelBuilder.Configurations.Add(new CustomerConfiguration()); 96 | 97 | return modelBuilder.Build(new DbProviderInfo("System.Data.SqlClient", "2008")); 98 | } 99 | } 100 | } 101 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.Tests/Fixtures/GenericFixtures/BaseUnitOfWorkFixture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NUnit.Framework; 3 | using System.Configuration; 4 | using System.IO; 5 | using System.Reflection; 6 | 7 | namespace Besnik.GenericRepository.Tests 8 | { 9 | /// 10 | /// Base fixture class for injecting unit of work implemenation. 11 | /// 12 | public abstract class BaseUnitOfWorkFixture 13 | { 14 | /// 15 | /// Constructor. 16 | /// 17 | public BaseUnitOfWorkFixture() 18 | { 19 | this.InitializeFactory(); 20 | this.InitializeConfiguration(); 21 | } 22 | 23 | /// 24 | /// Gets factory. 25 | /// 26 | protected Factory Factory = null; 27 | 28 | /// 29 | /// Gets unit of work factory. The factory usually wrapps an O/R mapper. 30 | /// 31 | protected IUnitOfWorkFactory UnitOfWorkFactory { get; private set; } 32 | 33 | /// 34 | /// Gets configuration of config file for the assembly. 35 | /// 36 | protected Configuration Configuration { get; private set; } 37 | 38 | /// 39 | /// Creates unit of work factory. Called only once in setup phase of the fixture. 40 | /// 41 | protected abstract IUnitOfWorkFactory CreateUnitOfWorkFactory(); 42 | 43 | /// 44 | /// Initializes data storage before each test case. 45 | /// 46 | protected abstract void InitializeDataStorage(); 47 | 48 | /// 49 | /// Initializes factory to build domain entities, mocks, stubs and necessary infrastructure. 50 | /// 51 | protected virtual void InitializeFactory() 52 | { 53 | this.Factory = new Factory(); 54 | } 55 | 56 | /// 57 | /// Initializes configuration for the assembly where this class resides. 58 | /// Use configuration to set your connection strings and custom application settings. 59 | /// 60 | protected virtual void InitializeConfiguration() 61 | { 62 | var exePath = Path.Combine( 63 | Environment.CurrentDirectory 64 | , Assembly.GetExecutingAssembly().ManifestModule.ScopeName 65 | ); 66 | 67 | if (!File.Exists(exePath)) 68 | { 69 | throw new Exception( 70 | string.Format("Config file {0} does not exists.", exePath) 71 | ); 72 | } 73 | 74 | this.Configuration = ConfigurationManager.OpenExeConfiguration(exePath); 75 | } 76 | 77 | /// 78 | /// Setups the fixture. 79 | /// 80 | [TestFixtureSetUp] 81 | public virtual void SetupFixture() 82 | { 83 | this.UnitOfWorkFactory = this.CreateUnitOfWorkFactory(); 84 | } 85 | 86 | /// 87 | /// Tears down the fixture. 88 | /// 89 | [TestFixtureTearDown] 90 | public virtual void TearDownFixture() 91 | { 92 | if (this.UnitOfWorkFactory != null) 93 | { 94 | this.UnitOfWorkFactory.Dispose(); 95 | this.UnitOfWorkFactory = null; 96 | } 97 | } 98 | 99 | /// 100 | /// Sets up the test case. 101 | /// 102 | [SetUp] 103 | public virtual void Setup() 104 | { 105 | this.InitializeDataStorage(); 106 | } 107 | 108 | /// 109 | /// Tests setup of each test case. See also method. 110 | /// 111 | [Test] 112 | public virtual void CreateSchema() 113 | { 114 | // empty, just testing method decorated with NUnit Setup attribute. 115 | } 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.Tests/Fixtures/GenericFixtures/GenericCustomerRepositoryFixture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Configuration; 3 | using System.IO; 4 | using System.Reflection; 5 | using NUnit.Framework; 6 | using Besnik.Domain; 7 | using Besnik.GenericRepository; 8 | using System.Collections.Generic; 9 | 10 | namespace Besnik.GenericRepository.Tests 11 | { 12 | /// 13 | /// Base class for customer repository integration tests. 14 | /// Derive and implement abstract functionality with concrete unit of work implementation. 15 | /// Do not forget decorate derived class with [TestFixture] attribute in order to execute 16 | /// the below generic tests. 17 | /// 18 | public abstract class GenericCustomerRepositoryFixture : BaseUnitOfWorkFixture 19 | { 20 | /// 21 | /// Template test method for adding customer into repository. 22 | /// 23 | [Test] 24 | public void AddItemToRepository_ExplicitFlush() 25 | { 26 | // arrange 27 | var customer = this.Factory.GetCustomer(); 28 | 29 | // act 30 | using ( var unitOfWork = this.UnitOfWorkFactory.BeginUnitOfWork() ) 31 | { 32 | ICustomerRepository cr = this.CreateCustomerRepository(unitOfWork); 33 | cr.Insert(customer); 34 | 35 | unitOfWork.Flush(); 36 | } 37 | 38 | // assert 39 | using ( var unitOfWork = this.UnitOfWorkFactory.BeginUnitOfWork() ) 40 | { 41 | var customerFromDb = this.GetCustomer(customer.Id, unitOfWork); 42 | 43 | Assert.That(customerFromDb, Is.Not.Null); 44 | Assert.That(customerFromDb, Is.Not.SameAs(customer)); 45 | Assert.That(customerFromDb.Name, Is.EqualTo(customer.Name)); 46 | Assert.That(customerFromDb.Age, Is.EqualTo(customer.Age)); 47 | } 48 | } 49 | 50 | /// 51 | /// Template test method for adding customer into repository. 52 | /// 53 | [Test] 54 | public void AddItemToRepository_NoFlush() 55 | { 56 | // arrange 57 | var customer = this.Factory.GetCustomer(); 58 | 59 | // act 60 | using ( var unitOfWork = this.UnitOfWorkFactory.BeginUnitOfWork() ) 61 | { 62 | ICustomerRepository cr = this.CreateCustomerRepository(unitOfWork); 63 | cr.Insert(customer); 64 | } 65 | 66 | // assert 67 | using ( var unitOfWork = this.UnitOfWorkFactory.BeginUnitOfWork() ) 68 | { 69 | var customerFromDb = this.GetCustomer(customer.Id, unitOfWork); 70 | 71 | Assert.That(customerFromDb, Is.Not.Null); 72 | Assert.That(customerFromDb, Is.Not.SameAs(customer)); 73 | Assert.That(customerFromDb.Name, Is.EqualTo(customer.Name)); 74 | Assert.That(customerFromDb.Age, Is.EqualTo(customer.Age)); 75 | } 76 | } 77 | 78 | /// 79 | /// Template test method for adding customer into repository. 80 | /// 81 | [Test] 82 | public void AddItemToRepository_NoFlushWithException() 83 | { 84 | // arrange 85 | var customer = this.Factory.GetCustomer(); 86 | Assert.That(customer.Id, Is.EqualTo(0)); 87 | 88 | // act 89 | try 90 | { 91 | using ( var unitOfWork = this.UnitOfWorkFactory.BeginUnitOfWork() ) 92 | { 93 | ICustomerRepository cr = this.CreateCustomerRepository(unitOfWork); 94 | cr.Insert(customer); 95 | 96 | throw new Exception("mocked ex"); 97 | } 98 | } 99 | catch 100 | { 101 | // assert 102 | using ( var unitOfWork = this.UnitOfWorkFactory.BeginUnitOfWork() ) 103 | { 104 | var customerFromDb = this.GetCustomer(customer.Id, unitOfWork); 105 | 106 | Assert.That(customerFromDb, Is.Not.Null); 107 | Assert.That(customerFromDb, Is.Not.SameAs(customer)); 108 | Assert.That(customerFromDb.Name, Is.EqualTo(customer.Name)); 109 | Assert.That(customerFromDb.Age, Is.EqualTo(customer.Age)); 110 | } 111 | } 112 | 113 | 114 | } 115 | 116 | /// 117 | /// Template test method for adding customer into repository in a transaction. 118 | /// 119 | [Test] 120 | public void AddItemsToRepositoryInTransaction() 121 | { 122 | // arrange 123 | var customer = this.Factory.GetCustomer(); 124 | 125 | // act 126 | using ( var unitOfWork = this.UnitOfWorkFactory.BeginUnitOfWork() ) 127 | { 128 | ICustomerRepository cr = this.CreateCustomerRepository(unitOfWork); 129 | 130 | using ( var transaction = unitOfWork.BeginTransaction() ) 131 | { 132 | cr.Insert(customer); 133 | 134 | transaction.Commit(); 135 | } 136 | } 137 | 138 | // assert 139 | using ( var unitOfWork = this.UnitOfWorkFactory.BeginUnitOfWork() ) 140 | { 141 | var customerFromDb = this.GetCustomer(customer.Id, unitOfWork); 142 | 143 | Assert.That(customerFromDb, Is.Not.Null); 144 | Assert.That(customerFromDb, Is.Not.SameAs(customer)); 145 | Assert.That(customerFromDb.Name, Is.EqualTo(customer.Name)); 146 | Assert.That(customerFromDb.Age, Is.EqualTo(customer.Age)); 147 | } 148 | } 149 | 150 | /// 151 | /// Template test method for adding customer into repository in a transaction that rolls back 152 | /// after an exception. 153 | /// 154 | [Test] 155 | public void AddItemsToRepositoryInTransaction_Rollback() 156 | { 157 | // arrange 158 | var customer = this.Factory.GetCustomer(); 159 | 160 | // act 161 | using ( var unitOfWork = this.UnitOfWorkFactory.BeginUnitOfWork() ) 162 | { 163 | try 164 | { 165 | ICustomerRepository cr = this.CreateCustomerRepository(unitOfWork); 166 | 167 | using ( var transaction = unitOfWork.BeginTransaction() ) 168 | { 169 | cr.Insert(customer); 170 | throw new Exception("mocked ex"); 171 | } 172 | } 173 | catch ( Exception ex ) 174 | { 175 | // assert 176 | Assert.That(ex.Message, Is.EqualTo("mocked ex")); 177 | 178 | using ( var innerUnitOfWork = this.UnitOfWorkFactory.BeginUnitOfWork() ) 179 | { 180 | var customerFromDb = this.GetCustomer(customer.Id, innerUnitOfWork); 181 | 182 | Assert.That(customerFromDb, Is.Null); 183 | } 184 | 185 | return; 186 | } 187 | } 188 | } 189 | 190 | /// 191 | /// Template test method for adding customer into repository. 192 | /// 193 | [Test] 194 | public void GetUsingSpecifiedAge() 195 | { 196 | // arrange 197 | var customer = this.Factory.GetCustomer(); 198 | 199 | using ( var unitOfWork = this.UnitOfWorkFactory.BeginUnitOfWork() ) 200 | { 201 | ICustomerRepository cr = this.CreateCustomerRepository(unitOfWork); 202 | cr.Insert(customer); 203 | } 204 | 205 | Customer c = null; 206 | 207 | // act 208 | using ( var unitOfWork = this.UnitOfWorkFactory.BeginUnitOfWork() ) 209 | { 210 | ICustomerRepository cr = this.CreateCustomerRepository(unitOfWork); 211 | c = cr.Specify() 212 | .WithAge(Factory.DefaultCustomerAge) 213 | .ToResult() 214 | .Single(); 215 | } 216 | 217 | // assert 218 | Assert.That(c, Is.Not.Null); 219 | Assert.That(c, Is.Not.SameAs(customer)); 220 | Assert.That(c.Name, Is.EqualTo(customer.Name)); 221 | Assert.That(c.Age, Is.EqualTo(customer.Age)); 222 | } 223 | 224 | /// 225 | /// Template test method for tesing Single method. In case the sequence contains 226 | /// no entities, the should be raised. 227 | /// 228 | [Test] 229 | [ExpectedException(typeof(InvalidOperationException))] 230 | public void SingleShouldThrow() 231 | { 232 | // arrange 233 | Customer c = null; 234 | 235 | // act 236 | using (var unitOfWork = this.UnitOfWorkFactory.BeginUnitOfWork()) 237 | { 238 | ICustomerRepository cr = this.CreateCustomerRepository(unitOfWork); 239 | c = cr.Specify() 240 | .ToResult() 241 | .Single(); 242 | } 243 | 244 | // assert 245 | Assert.Fail(); 246 | } 247 | 248 | /// 249 | /// Template test method for tesing SingleOrDefault method. In case the sequence contains 250 | /// no entities, null should be the result. 251 | /// 252 | [Test] 253 | public void SingleOrDefaultShouldNotThrow() 254 | { 255 | // arrange 256 | Customer c = null; 257 | 258 | // act 259 | using (var unitOfWork = this.UnitOfWorkFactory.BeginUnitOfWork()) 260 | { 261 | ICustomerRepository cr = this.CreateCustomerRepository(unitOfWork); 262 | c = cr.Specify() 263 | .ToResult() 264 | .SingleOrDefault(); 265 | } 266 | 267 | // assert 268 | Assert.That(c, Is.Null); 269 | } 270 | 271 | /// 272 | /// Template test method for ascending ordering. 273 | /// 274 | [Test] 275 | public void GetCustomersOrderByAgeAscending() 276 | { 277 | // arrange 278 | var customer1 = this.Factory.GetCustomer("Peter Bondra", 38); 279 | var customer2 = this.Factory.GetCustomer("Miroslav Satan", 32); 280 | var customer3 = this.Factory.GetCustomer("Zigmund Palffy", 34); 281 | 282 | using (var unitOfWork = this.UnitOfWorkFactory.BeginUnitOfWork()) 283 | { 284 | ICustomerRepository cr = this.CreateCustomerRepository(unitOfWork); 285 | cr.Insert(customer1); 286 | cr.Insert(customer2); 287 | cr.Insert(customer3); 288 | } 289 | 290 | IList customers = null; 291 | 292 | // act 293 | using (var unitOfWork = this.UnitOfWorkFactory.BeginUnitOfWork()) 294 | { 295 | ICustomerRepository cr = this.CreateCustomerRepository(unitOfWork); 296 | customers = cr.Specify() 297 | .ToResult() 298 | .OrderByAscending(c => c.Age) 299 | .ToList(); 300 | } 301 | 302 | // assert 303 | Assert.That(customers, Is.Not.Null); 304 | Assert.That(customers.Count, Is.EqualTo(3)); 305 | Assert.That(customers[0].Age, Is.LessThanOrEqualTo(customers[1].Age)); 306 | Assert.That(customers[1].Age, Is.LessThanOrEqualTo(customers[2].Age)); 307 | } 308 | 309 | /// 310 | /// Template test method for descending ordering. 311 | /// 312 | [Test] 313 | public void GetCustomersOrderByAgeDescending() 314 | { 315 | // arrange 316 | var customer1 = this.Factory.GetCustomer("Peter Bondra", 38); 317 | var customer2 = this.Factory.GetCustomer("Miroslav Satan", 32); 318 | var customer3 = this.Factory.GetCustomer("Zigmund Palffy", 34); 319 | 320 | using (var unitOfWork = this.UnitOfWorkFactory.BeginUnitOfWork()) 321 | { 322 | ICustomerRepository cr = this.CreateCustomerRepository(unitOfWork); 323 | cr.Insert(customer1); 324 | cr.Insert(customer2); 325 | cr.Insert(customer3); 326 | } 327 | 328 | IList customers = null; 329 | 330 | // act 331 | using (var unitOfWork = this.UnitOfWorkFactory.BeginUnitOfWork()) 332 | { 333 | ICustomerRepository cr = this.CreateCustomerRepository(unitOfWork); 334 | customers = cr.Specify() 335 | .ToResult() 336 | .OrderByDescending(c => c.Age) 337 | .ToList(); 338 | } 339 | 340 | // assert 341 | Assert.That(customers, Is.Not.Null); 342 | Assert.That(customers.Count, Is.EqualTo(3)); 343 | Assert.That(customers[0].Age, Is.GreaterThanOrEqualTo(customers[1].Age)); 344 | Assert.That(customers[1].Age, Is.GreaterThanOrEqualTo(customers[2].Age)); 345 | } 346 | 347 | /// 348 | /// Template test method for checking Skip functionality. 349 | /// 350 | [Test] 351 | public void GetCustomersButSkipSome() 352 | { 353 | // arrange 354 | var customer1 = this.Factory.GetCustomer("Peter Bondra", 38); 355 | var customer2 = this.Factory.GetCustomer("Miroslav Satan", 32); 356 | var customer3 = this.Factory.GetCustomer("Zigmund Palffy", 34); 357 | 358 | using (var unitOfWork = this.UnitOfWorkFactory.BeginUnitOfWork()) 359 | { 360 | ICustomerRepository cr = this.CreateCustomerRepository(unitOfWork); 361 | cr.Insert(customer1); 362 | cr.Insert(customer2); 363 | cr.Insert(customer3); 364 | } 365 | 366 | IList customers = null; 367 | 368 | // act 369 | using (var unitOfWork = this.UnitOfWorkFactory.BeginUnitOfWork()) 370 | { 371 | ICustomerRepository cr = this.CreateCustomerRepository(unitOfWork); 372 | /* Important: only NHibernate correctly process the result. 373 | * 374 | * Entity framework: before Skip() the OrderBy has to be called! 375 | * 376 | * Linq2Sql: if orderby is called after Skip(), the order by is ignored then! 377 | * 378 | * Note: try to remove OrderByAscending, you will see that only NHibernate and 379 | * Linq2Sql is able to process the request. 380 | * 381 | * Note2: try to put OrderByAscending AFTER Skip() and adapt last assert. 382 | * Only NHibernate is able to return correct result. Linq2Sql ignores ordering! 383 | */ 384 | customers = cr.Specify() 385 | .ToResult() 386 | .OrderByAscending(c => c.Age) 387 | .Skip(2) 388 | .ToList(); 389 | } 390 | 391 | // assert 392 | Assert.That(customers, Is.Not.Null); 393 | Assert.That(customers.Count, Is.EqualTo(1)); 394 | Assert.That(customers[0].Age, Is.EqualTo(38)); 395 | } 396 | 397 | /// 398 | /// Template test method for ToList method if collection of entities is empty. 399 | /// Specification is used to select entities. 400 | /// 401 | [Test] 402 | public void GetCustomersToListButReceivedNoData() 403 | { 404 | // arrange 405 | 406 | IList customers = null; 407 | 408 | // act 409 | using (var unitOfWork = this.UnitOfWorkFactory.BeginUnitOfWork()) 410 | { 411 | ICustomerRepository cr = this.CreateCustomerRepository(unitOfWork); 412 | customers = cr.Specify() 413 | .ToResult() 414 | .ToList(); 415 | } 416 | 417 | // assert 418 | Assert.That(customers, Is.Not.Null); 419 | Assert.That(customers.Count, Is.EqualTo(0)); 420 | } 421 | 422 | /// 423 | /// Template test method for GetAll method if collection of entities is empty. 424 | /// 425 | [Test] 426 | public void GetAllCustomersIfReceivedNoData() 427 | { 428 | // arrange 429 | 430 | IList customers = null; 431 | 432 | // act 433 | using (var unitOfWork = this.UnitOfWorkFactory.BeginUnitOfWork()) 434 | { 435 | ICustomerRepository cr = this.CreateCustomerRepository(unitOfWork); 436 | customers = cr.GetAll(); 437 | } 438 | 439 | // assert 440 | Assert.That(customers, Is.Not.Null); 441 | Assert.That(customers.Count, Is.EqualTo(0)); 442 | } 443 | 444 | /// 445 | /// Creates unit of work implementation specific repository. 446 | /// 447 | protected abstract ICustomerRepository CreateCustomerRepository(IUnitOfWork unitOfWork); 448 | 449 | /// 450 | /// Loads customer from given data storage. 451 | /// 452 | protected abstract Customer GetCustomer(int customerId, IUnitOfWork unitOfWork); 453 | } 454 | } 455 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.Tests/Fixtures/LinqToSqlFixtures/LinqToSqlCustomerRepositoryFixture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Data.Linq; 3 | using System.Data.Linq.Mapping; 4 | using System.Linq; 5 | using System.Reflection; 6 | using Besnik.Domain; 7 | using Besnik.GenericRepository; 8 | using NUnit.Framework; 9 | using Besnik.GenericRepository.LinqToSql; 10 | using Besnik.Domain.LinqToSqlRepository; 11 | 12 | namespace Besnik.GenericRepository.Tests 13 | { 14 | [TestFixture] 15 | public class LinqToSqlCustomerRepositoryFixture : GenericCustomerRepositoryFixture 16 | { 17 | protected override IUnitOfWorkFactory CreateUnitOfWorkFactory() 18 | { 19 | return new LinqToSqlUnitOfWorkFactory( 20 | this.GetConnectionString() 21 | , this.GetMapping() 22 | ); 23 | } 24 | 25 | protected override void InitializeDataStorage() 26 | { 27 | // next line ensures the domain assembly is loaded into app domain. 28 | // this is necessary for linq2sql in order to correctly load xml mapping file. 29 | // since we haven't used domain functionaly anywhere yet, next line causes .NET to 30 | // load domain assmebly into app domain. 31 | Type t = typeof(ICustomerSpecification); 32 | 33 | var mapping = this.GetMapping(); 34 | 35 | var tables = mapping.GetModel(typeof(DataContext)).GetTables(); 36 | 37 | // deletes content of all tables 38 | foreach ( var table in tables ) 39 | { 40 | using ( var unitOfWork = ( this.UnitOfWorkFactory as LinqToSqlUnitOfWorkFactory ).BeginUnitOfWork() ) 41 | { 42 | ( unitOfWork as LinqToSqlUnitOfWork ).DataContext.ExecuteQuery( 43 | string.Format("delete from {0}", table.TableName) 44 | ); 45 | 46 | } 47 | 48 | } 49 | } 50 | 51 | protected override ICustomerRepository CreateCustomerRepository(IUnitOfWork unitOfWork) 52 | { 53 | var specificationLocator = this.Factory.GetSpecificationLocatorForLinqToSql(); 54 | return new CustomerRepository(unitOfWork, specificationLocator); 55 | } 56 | 57 | protected override Customer GetCustomer(int customerId, IUnitOfWork unitOfWork) 58 | { 59 | var dc = ( unitOfWork as LinqToSqlUnitOfWork ).DataContext; 60 | var table = dc.GetTable(); 61 | return table.FirstOrDefault(c => c.Id == customerId); 62 | } 63 | 64 | /// 65 | /// Gets key in connection strings section used to load connection string from app.config. 66 | /// 67 | protected virtual string ConnectionStringKey 68 | { 69 | get 70 | { 71 | return "Linq2SqlConnectionString"; 72 | } 73 | } 74 | 75 | /// 76 | /// Gets connection string from config file used to initialize Linq2Sql data context. 77 | /// 78 | protected virtual string GetConnectionString() 79 | { 80 | return this.Configuration.ConnectionStrings.ConnectionStrings[ConnectionStringKey].ConnectionString; 81 | } 82 | 83 | /// 84 | /// Gets mapping to initialize Linq2Sql data context. 85 | /// 86 | /// 87 | /// Fixture expects the linq2sql implementation contains one and only embedded resource file 88 | /// with mapping configuration. 89 | /// 90 | protected virtual MappingSource GetMapping() 91 | { 92 | var executingAssembly = Assembly.GetAssembly(typeof(CustomerRepository)); 93 | 94 | var customerMappingFileName = 95 | ( from r in executingAssembly.GetManifestResourceNames().AsEnumerable() 96 | where r.EndsWith(".linq2sql.xml") 97 | select r ).Single(); 98 | 99 | var customerMappingFile = executingAssembly.GetManifestResourceStream(customerMappingFileName); 100 | return XmlMappingSource.FromStream(customerMappingFile); 101 | } 102 | } 103 | } 104 | 105 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.Tests/Fixtures/NHibernateFixtures/NHibernateCriteriaFixture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NUnit.Framework; 3 | using Besnik.Domain; 4 | using Besnik.Domain.NHibernateRepository; 5 | 6 | namespace Besnik.GenericRepository.Tests 7 | { 8 | [TestFixture] 9 | public class NHibernateCriteriaFixture : NHibernateUnitOfWorkFixture 10 | { 11 | [Test] 12 | public void CriteriaSpecificationTest() 13 | { 14 | // arrange 15 | var customer = this.Factory.GetCustomer(); 16 | 17 | using (var unitOfWork = this.UnitOfWorkFactory.BeginUnitOfWork()) 18 | { 19 | ICustomerRepository cr = this.CreateCustomerRepository(unitOfWork); 20 | cr.Insert(customer); 21 | } 22 | 23 | Customer c = null; 24 | 25 | // act 26 | using (var unitOfWork = this.UnitOfWorkFactory.BeginUnitOfWork()) 27 | { 28 | ICustomerRepository cr = this.CreateCustomerRepository(unitOfWork); 29 | c = cr.Specify() 30 | .WithAge(Factory.DefaultCustomerAge) 31 | .ToResult() 32 | .Single(); 33 | } 34 | 35 | // assert 36 | Assert.That(c, Is.Not.Null); 37 | Assert.That(c, Is.Not.SameAs(customer)); 38 | Assert.That(c.Name, Is.EqualTo(customer.Name)); 39 | Assert.That(c.Age, Is.EqualTo(customer.Age)); 40 | } 41 | 42 | protected ICustomerRepository CreateCustomerRepository(IUnitOfWork unitOfWork) 43 | { 44 | // repository 45 | var specificationLocator = this.Factory.GetSpecificationLocatorForNHibernateWithCriteria(); 46 | return new CustomerRepository(unitOfWork, specificationLocator); 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.Tests/Fixtures/NHibernateFixtures/NHibernateCustomerRepositoryFixture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using NUnit.Framework; 4 | using Besnik.Domain; 5 | using Besnik.GenericRepository; 6 | using Besnik.GenericRepository.NHibernate; 7 | using Besnik.Domain.NHibernateRepository; 8 | 9 | namespace Besnik.GenericRepository.Tests 10 | { 11 | [TestFixture] 12 | public class NHibernateCustomerRepositoryFixture : GenericCustomerRepositoryFixture 13 | { 14 | protected override IUnitOfWorkFactory CreateUnitOfWorkFactory() 15 | { 16 | return new NHibernateUnitOfWorkFactory( 17 | this.GetNHibernateConfigPath() 18 | , typeof(CustomerRepository).Assembly 19 | ); 20 | } 21 | 22 | protected override void InitializeDataStorage() 23 | { 24 | ( this.UnitOfWorkFactory as NHibernateUnitOfWorkFactory ).NHibernateSchemaExport(); 25 | } 26 | 27 | /// 28 | /// Gets absolute path to the NHibernate config path. 29 | /// 30 | protected virtual string GetNHibernateConfigPath() 31 | { 32 | return Path.Combine( 33 | Environment.CurrentDirectory 34 | , Factory.NHibernateConfigPath 35 | ); 36 | } 37 | 38 | protected override ICustomerRepository CreateCustomerRepository(IUnitOfWork unitOfWork) 39 | { 40 | // repository 41 | var specificationLocator = this.Factory.GetSpecificationLocatorForNHibernate(); 42 | return new CustomerRepository(unitOfWork, specificationLocator); 43 | } 44 | 45 | protected override Customer GetCustomer(int customerId, IUnitOfWork unitOfWork) 46 | { 47 | var session = ( unitOfWork as NHibernateUnitOfWork ).Session; 48 | return session.Get(customerId); 49 | } 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.Tests/Fixtures/NHibernateFixtures/NHibernateUnitOfWorkFixture.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using NUnit.Framework; 3 | using Besnik.GenericRepository.NHibernate; 4 | using Besnik.Domain.NHibernateRepository; 5 | using System.IO; 6 | 7 | namespace Besnik.GenericRepository.Tests 8 | { 9 | /// 10 | /// Base class for nhibernate unit of work fixtures. 11 | /// 12 | public abstract class NHibernateUnitOfWorkFixture : BaseUnitOfWorkFixture 13 | { 14 | protected override IUnitOfWorkFactory CreateUnitOfWorkFactory() 15 | { 16 | return new NHibernateUnitOfWorkFactory( 17 | this.GetNHibernateConfigPath() 18 | , typeof(CustomerRepository).Assembly 19 | ); 20 | } 21 | 22 | protected override void InitializeDataStorage() 23 | { 24 | (this.UnitOfWorkFactory as NHibernateUnitOfWorkFactory).NHibernateSchemaExport(); 25 | } 26 | 27 | protected virtual string NHibernateConfigPath 28 | { 29 | get 30 | { 31 | return Factory.NHibernateConfigPath; 32 | } 33 | } 34 | 35 | /// 36 | /// Gets absolute path to the NHibernate config path. 37 | /// 38 | protected string GetNHibernateConfigPath() 39 | { 40 | return Path.Combine( 41 | Environment.CurrentDirectory 42 | , NHibernateConfigPath 43 | ); 44 | } 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.Tests/Mocks/SpecificationLocatorStub.cs: -------------------------------------------------------------------------------- 1 | using Autofac; 2 | using Besnik.GenericRepository; 3 | 4 | namespace Besnik.GenericRepository.Tests 5 | { 6 | public class SpecificationLocatorStub : ISpecificationLocator 7 | { 8 | public SpecificationLocatorStub(IContainer container) 9 | { 10 | this.Container = container; 11 | } 12 | 13 | protected IContainer Container { get; private set; } 14 | 15 | public TSpecification Resolve() 16 | where TSpecification : ISpecification 17 | where TEntity : class 18 | { 19 | return this.Container.Resolve(); 20 | } 21 | } 22 | } 23 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.Tests/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Besnik.GenericRepository.Tests")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("")] 13 | [assembly: AssemblyCopyright("")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("5a6fc88c-673e-4f36-90ee-5fdbdc20ba7f")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.1.0.*")] 36 | [assembly: AssemblyFileVersion("1.1.0.0")] 37 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.Tests/packages.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | -------------------------------------------------------------------------------- /Besnik.GenericRepository.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Besnik.GenericRepository", "Besnik.GenericRepository\Besnik.GenericRepository.csproj", "{1C33F903-59B8-437C-8637-94CB394CA970}" 5 | EndProject 6 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Besnik.Domain.NHibernateRepository", "Besnik.Domain.NHibernate\Besnik.Domain.NHibernate.csproj", "{ABDD5544-3CAA-49FB-A06A-895585BA55B2}" 7 | EndProject 8 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Besnik.Domain", "Besnik.Domain\Besnik.Domain.csproj", "{D5B52DDB-C986-4055-9CAC-5526F42B8A93}" 9 | EndProject 10 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Besnik.GenericRepository.Tests", "Besnik.GenericRepository.Tests\Besnik.GenericRepository.Tests.csproj", "{1AA5D032-863A-4952-A00A-E48475E9CB9D}" 11 | EndProject 12 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Besnik.Domain.LinqToSqlRepository", "Besnik.Domain.LinqToSql\Besnik.Domain.LinqToSql.csproj", "{C6CC3E66-9506-43D7-BE8F-0C49D59C34E3}" 13 | EndProject 14 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Besnik.GenericRepository.NHibernate", "Besnik.GenericRepository.NHibernate\Besnik.GenericRepository.NHibernate.csproj", "{DCC5973E-B6BC-4A41-8996-ED4AFBEEB318}" 15 | EndProject 16 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Besnik.GenericRepository.LinqToSql", "Besnik.GenericRepository.LinqToSql\Besnik.GenericRepository.LinqToSql.csproj", "{207ADEBC-CCE9-4ACC-AEA8-E086BB23A638}" 17 | EndProject 18 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Besnik.GenericRepository.EntityFramework", "Besnik.GenericRepository.EntityFramework\Besnik.GenericRepository.EntityFramework.csproj", "{5630007D-50C9-4D99-A734-BBE7451B1C3D}" 19 | EndProject 20 | Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Besnik.Domain.EntityFramework", "Besnik.Domain.EntityFramework\Besnik.Domain.EntityFramework.csproj", "{B3288165-24F4-49AF-A7B5-79B027F82EC8}" 21 | EndProject 22 | Global 23 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 24 | Debug|Any CPU = Debug|Any CPU 25 | Release|Any CPU = Release|Any CPU 26 | EndGlobalSection 27 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 28 | {1C33F903-59B8-437C-8637-94CB394CA970}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 29 | {1C33F903-59B8-437C-8637-94CB394CA970}.Debug|Any CPU.Build.0 = Debug|Any CPU 30 | {1C33F903-59B8-437C-8637-94CB394CA970}.Release|Any CPU.ActiveCfg = Release|Any CPU 31 | {1C33F903-59B8-437C-8637-94CB394CA970}.Release|Any CPU.Build.0 = Release|Any CPU 32 | {ABDD5544-3CAA-49FB-A06A-895585BA55B2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 33 | {ABDD5544-3CAA-49FB-A06A-895585BA55B2}.Debug|Any CPU.Build.0 = Debug|Any CPU 34 | {ABDD5544-3CAA-49FB-A06A-895585BA55B2}.Release|Any CPU.ActiveCfg = Release|Any CPU 35 | {ABDD5544-3CAA-49FB-A06A-895585BA55B2}.Release|Any CPU.Build.0 = Release|Any CPU 36 | {D5B52DDB-C986-4055-9CAC-5526F42B8A93}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 37 | {D5B52DDB-C986-4055-9CAC-5526F42B8A93}.Debug|Any CPU.Build.0 = Debug|Any CPU 38 | {D5B52DDB-C986-4055-9CAC-5526F42B8A93}.Release|Any CPU.ActiveCfg = Release|Any CPU 39 | {D5B52DDB-C986-4055-9CAC-5526F42B8A93}.Release|Any CPU.Build.0 = Release|Any CPU 40 | {1AA5D032-863A-4952-A00A-E48475E9CB9D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 41 | {1AA5D032-863A-4952-A00A-E48475E9CB9D}.Debug|Any CPU.Build.0 = Debug|Any CPU 42 | {1AA5D032-863A-4952-A00A-E48475E9CB9D}.Release|Any CPU.ActiveCfg = Release|Any CPU 43 | {1AA5D032-863A-4952-A00A-E48475E9CB9D}.Release|Any CPU.Build.0 = Release|Any CPU 44 | {C6CC3E66-9506-43D7-BE8F-0C49D59C34E3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 45 | {C6CC3E66-9506-43D7-BE8F-0C49D59C34E3}.Debug|Any CPU.Build.0 = Debug|Any CPU 46 | {C6CC3E66-9506-43D7-BE8F-0C49D59C34E3}.Release|Any CPU.ActiveCfg = Release|Any CPU 47 | {C6CC3E66-9506-43D7-BE8F-0C49D59C34E3}.Release|Any CPU.Build.0 = Release|Any CPU 48 | {DCC5973E-B6BC-4A41-8996-ED4AFBEEB318}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 49 | {DCC5973E-B6BC-4A41-8996-ED4AFBEEB318}.Debug|Any CPU.Build.0 = Debug|Any CPU 50 | {DCC5973E-B6BC-4A41-8996-ED4AFBEEB318}.Release|Any CPU.ActiveCfg = Release|Any CPU 51 | {DCC5973E-B6BC-4A41-8996-ED4AFBEEB318}.Release|Any CPU.Build.0 = Release|Any CPU 52 | {207ADEBC-CCE9-4ACC-AEA8-E086BB23A638}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 53 | {207ADEBC-CCE9-4ACC-AEA8-E086BB23A638}.Debug|Any CPU.Build.0 = Debug|Any CPU 54 | {207ADEBC-CCE9-4ACC-AEA8-E086BB23A638}.Release|Any CPU.ActiveCfg = Release|Any CPU 55 | {207ADEBC-CCE9-4ACC-AEA8-E086BB23A638}.Release|Any CPU.Build.0 = Release|Any CPU 56 | {5630007D-50C9-4D99-A734-BBE7451B1C3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 57 | {5630007D-50C9-4D99-A734-BBE7451B1C3D}.Debug|Any CPU.Build.0 = Debug|Any CPU 58 | {5630007D-50C9-4D99-A734-BBE7451B1C3D}.Release|Any CPU.ActiveCfg = Release|Any CPU 59 | {5630007D-50C9-4D99-A734-BBE7451B1C3D}.Release|Any CPU.Build.0 = Release|Any CPU 60 | {B3288165-24F4-49AF-A7B5-79B027F82EC8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU 61 | {B3288165-24F4-49AF-A7B5-79B027F82EC8}.Debug|Any CPU.Build.0 = Debug|Any CPU 62 | {B3288165-24F4-49AF-A7B5-79B027F82EC8}.Release|Any CPU.ActiveCfg = Release|Any CPU 63 | {B3288165-24F4-49AF-A7B5-79B027F82EC8}.Release|Any CPU.Build.0 = Release|Any CPU 64 | EndGlobalSection 65 | GlobalSection(SolutionProperties) = preSolution 66 | HideSolutionNode = FALSE 67 | EndGlobalSection 68 | EndGlobal 69 | -------------------------------------------------------------------------------- /Besnik.GenericRepository/Besnik.GenericRepository.csproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | Debug 5 | AnyCPU 6 | 9.0.30729 7 | 2.0 8 | {1C33F903-59B8-437C-8637-94CB394CA970} 9 | Library 10 | Properties 11 | Besnik.GenericRepository 12 | Besnik.GenericRepository 13 | v4.0 14 | 512 15 | 16 | 17 | 3.5 18 | 19 | publish\ 20 | true 21 | Disk 22 | false 23 | Foreground 24 | 7 25 | Days 26 | false 27 | false 28 | true 29 | 0 30 | 1.0.0.%2a 31 | false 32 | false 33 | true 34 | 35 | 36 | 37 | true 38 | full 39 | false 40 | bin\Debug\ 41 | DEBUG;TRACE 42 | prompt 43 | 4 44 | AllRules.ruleset 45 | bin\Debug\Besnik.GenericRepository.xml 46 | 47 | 48 | pdbonly 49 | true 50 | bin\Release\ 51 | TRACE 52 | prompt 53 | 4 54 | AllRules.ruleset 55 | bin\Release\Besnik.GenericRepository.xml 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | False 75 | .NET Framework 3.5 SP1 Client Profile 76 | false 77 | 78 | 79 | False 80 | .NET Framework 3.5 SP1 81 | true 82 | 83 | 84 | False 85 | Windows Installer 3.1 86 | true 87 | 88 | 89 | 90 | 91 | 92 | 93 | 100 | -------------------------------------------------------------------------------- /Besnik.GenericRepository/Exceptions/GenericRepositoryException.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Besnik.GenericRepository 4 | { 5 | /// 6 | /// Signalizes general error in generic repository. 7 | /// 8 | public class GenericRepositoryException : Exception 9 | { 10 | /// 11 | /// Initializes a new instance of the class. 12 | /// 13 | public GenericRepositoryException() 14 | : base() 15 | { 16 | } 17 | 18 | /// 19 | /// Initializes a new instance of the class. 20 | /// 21 | /// The error message. 22 | public GenericRepositoryException(string message) 23 | : base(message) 24 | { 25 | } 26 | 27 | /// 28 | /// Initializes a new instance of the class. 29 | /// 30 | /// The error message. 31 | /// The inner exception 32 | public GenericRepositoryException(string message, Exception innerException) 33 | : base(message, innerException) 34 | { 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /Besnik.GenericRepository/GenericRepository/GenericRepository.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Besnik.GenericRepository 5 | { 6 | /// 7 | /// Generic repository wraps given implementation 8 | /// and provides unified access to the entities stored in underlying data storage. 9 | /// 10 | /// 11 | /// Additionally to , the repository supports 12 | /// fluently initialized specifications. See also method. 13 | /// 14 | /// All commands have to be executed over started unit of work session. 15 | /// 16 | /// Flushing of entities to underlying data storage is in competence of 17 | /// given unit of work. In other words, synchronization between in-memory repository 18 | /// and data storage (e.g. database) is done via unit of work. This way the client 19 | /// has complete control over calling data storage and can optimize the way the entities 20 | /// are managed. 21 | /// 22 | public class GenericRepository : IGenericRepository 23 | where TEntity : class 24 | { 25 | /// 26 | /// Constructor. 27 | /// 28 | /// Unit of work for concrete implementation of data mapper. 29 | /// Specification locator resolves implementations of 30 | /// interface. is normally 31 | /// wrapper over IoC container. 32 | public GenericRepository( 33 | IUnitOfWork unitOfWork 34 | , ISpecificationLocator specificationLocator 35 | ) 36 | { 37 | this.EnsureNotNull(specificationLocator); 38 | this.EnsureNotNull(unitOfWork); 39 | 40 | this.SpecificationLocator = specificationLocator; 41 | this.UnitOfWork = unitOfWork; 42 | } 43 | 44 | /// 45 | /// Checks if given instance is not null. Use the method to validate input parameters. 46 | /// 47 | protected void EnsureNotNull(object o) 48 | { 49 | if (o == null) 50 | { 51 | throw new ArgumentNullException("o", "Argument can not be null."); 52 | } 53 | } 54 | 55 | /// 56 | /// Gets specification locator for the repository to resolve specifications. 57 | /// 58 | protected ISpecificationLocator SpecificationLocator { get; private set; } 59 | 60 | /// 61 | /// Gets unit of work the repository operates on. 62 | /// 63 | protected IUnitOfWork UnitOfWork { get; private set; } 64 | 65 | /// 66 | /// Inserts entity to the repository. 67 | /// 68 | public virtual void Insert(TEntity entity) 69 | { 70 | this.UnitOfWork.Insert(entity); 71 | } 72 | 73 | /// 74 | /// Updates entity in the repository. 75 | /// 76 | public virtual void Update(TEntity entity) 77 | { 78 | this.UnitOfWork.Update(entity); 79 | } 80 | 81 | /// 82 | /// Deletes entity from the repository. 83 | /// 84 | public virtual void Delete(TEntity entity) 85 | { 86 | this.UnitOfWork.Delete(entity); 87 | } 88 | 89 | /// 90 | /// Gets entity from the repository by given id. 91 | /// 92 | /// Primary key that identifies the entity. 93 | public virtual TEntity GetById(TPrimaryKey id) 94 | { 95 | return this.UnitOfWork.GetById(id); 96 | } 97 | 98 | /// 99 | /// Gets all entities from the repository. 100 | /// 101 | public virtual IList GetAll() 102 | { 103 | return this.UnitOfWork.GetAll(); 104 | } 105 | 106 | /// 107 | /// Gets specification that allows to filter only requested entities 108 | /// from the repository. 109 | /// 110 | /// Concrete specification that will be resolved 111 | /// and initialized with underlying unit of work instance. This ensures fluent 112 | /// and strongly typed way of connecting repository (uow) and specifications. 113 | public virtual TSpecification Specify() 114 | where TSpecification : class, ISpecification 115 | { 116 | TSpecification specification = default(TSpecification); 117 | 118 | try 119 | { 120 | specification = this.SpecificationLocator.Resolve(); 121 | } 122 | catch (Exception ex) 123 | { 124 | throw new GenericRepositoryException( 125 | string.Format( 126 | "Could not resolve requested specification {0} for entity {1} from the specification locator." 127 | , typeof(TSpecification).FullName 128 | , typeof(TEntity).FullName 129 | ) 130 | , ex 131 | ); 132 | } 133 | 134 | specification.Initialize(UnitOfWork); 135 | return specification; 136 | } 137 | } 138 | } 139 | -------------------------------------------------------------------------------- /Besnik.GenericRepository/Interfaces/IGenericRepository.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | 3 | namespace Besnik.GenericRepository 4 | { 5 | /// 6 | /// Generic repository interface (DDD) for reading and writing domain entities to a storage. 7 | /// 8 | /// Domain entity. 9 | /// Type of the primary key. 10 | public interface IGenericRepository where TEntity : class 11 | { 12 | /// 13 | /// Inserts entity to the storage. 14 | /// 15 | void Insert(TEntity entity); 16 | 17 | /// 18 | /// Updates entity in the storage. 19 | /// 20 | void Update(TEntity entity); 21 | 22 | /// 23 | /// Deletes entity in the storage. 24 | /// 25 | void Delete(TEntity entity); 26 | 27 | /// 28 | /// Gets entity from the storage by it's Id. 29 | /// 30 | TEntity GetById(TPrimaryKey id); 31 | 32 | /// 33 | /// Gets all entities of the type from the storage. 34 | /// 35 | IList GetAll(); 36 | 37 | /// 38 | /// Gets specification interface for complex searching for an entity or entities. 39 | /// 40 | /// Concrete specification that will be resolved 41 | /// and initialized with underlying unit of work instance. This ensures fluent 42 | /// and strongly typed way of connecting repository (uow) and specifications. 43 | TSpecification Specify() where TSpecification : class, ISpecification; 44 | } 45 | } 46 | -------------------------------------------------------------------------------- /Besnik.GenericRepository/Interfaces/ISpecification.cs: -------------------------------------------------------------------------------- 1 | namespace Besnik.GenericRepository 2 | { 3 | /// 4 | /// Generic base interface for the domain specifications (domain oriented queries). 5 | /// 6 | /// 7 | /// Specification pattern belongs to the domain patterns family. It is used in 8 | /// Domain Driven Design (DDD) world. Name of the methods of derivate interfaces 9 | /// are matching the domain and it's context. It is domain oriented. 10 | /// 11 | /// In comparison the Query pattern belogs to the (generic) design patterns family. 12 | /// The pattern is focused more on generic and technical side of the problem. 13 | /// Example is NHibernate and it's criterion query objects pattern implementation. 14 | /// 15 | /// If your specification have different requirements, you can implement other public 16 | /// method than . returns 17 | /// the type that is specified in type parameter, so all methods are visible 18 | /// to the client. For example, it would be possible to create specification that 19 | /// specifies several input data and has Execute method that writes something into 20 | /// underlying unit of work. 21 | /// 22 | public interface ISpecification 23 | where TEntity : class 24 | { 25 | /// 26 | /// Initializes specification from given unit of work instance. 27 | /// 28 | void Initialize(IUnitOfWork unitOfWork); 29 | 30 | /// 31 | /// Gets specification result wrapped into interface. 32 | /// 33 | /// 34 | /// interface wrapps common functionality that is shared 35 | /// accross all specifications. 36 | /// 37 | ISpecificationResult ToResult(); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /Besnik.GenericRepository/Interfaces/ISpecificationLocator.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Besnik.GenericRepository 4 | { 5 | /// 6 | /// The interface resolves specifications for a repository. 7 | /// The concrete implementation this usually wrapper over an IoC container. 8 | /// 9 | public interface ISpecificationLocator 10 | { 11 | /// 12 | /// Gets requested specification for given entity. 13 | /// 14 | TSpecification Resolve() 15 | where TSpecification : ISpecification 16 | where TEntity : class; 17 | } 18 | } 19 | -------------------------------------------------------------------------------- /Besnik.GenericRepository/Interfaces/ISpecificationResult.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq.Expressions; 3 | using System; 4 | 5 | namespace Besnik.GenericRepository 6 | { 7 | /// 8 | /// Generic domain specification result interface that 9 | /// contains methods common for filtering the result. 10 | /// 11 | /// 12 | /// If the specification model uses lazy loading using , 13 | /// this is the place where the query is translated and executed by calling for example 14 | /// or methods. 15 | /// 16 | /// The interface is very similar to IQueryable interface. It is basically 17 | /// the wrapper over the IQueryable if used under the hood. The main goal is to 18 | /// provide set of common methods used by all specifications. Other methods that 19 | /// normally IQueryable supports should be implemented in 20 | /// interface using strong domain names of the method (e.g. joins, grouping, agregate functions). 21 | /// 22 | /// Note it is perfectly fine if from domain perspective the specification already 23 | /// uses the functionality of this specification result. The specification should represents 24 | /// one query that can be customized using fluent interface but in general it should be 25 | /// strongly domain focused. 26 | /// 27 | public interface ISpecificationResult where TEntity : class 28 | { 29 | /// 30 | /// Takes given count of domain objects. 31 | /// 32 | ISpecificationResult Take(int count); 33 | 34 | /// 35 | /// Bypasses a specified number of elements in a sequence and then returns 36 | /// the remaining elements. 37 | /// 38 | /// The number of elements to skip before returning 39 | /// the remaining elements. 40 | ISpecificationResult Skip(int count); 41 | 42 | /// 43 | /// Sorts the elements of a sequence in ascending order according to a key. 44 | /// 45 | /// The type of the key returned by the function that is 46 | /// represented by keySelector. 47 | /// A function to extract a key from an element. 48 | ISpecificationResult OrderByAscending(Expression> keySelector); 49 | 50 | /// 51 | /// Sorts the elements of a sequence in descending order according to a key. 52 | /// 53 | /// The type of the key returned by the function that is 54 | /// represented by keySelector. 55 | /// A function to extract a key from an element. 56 | ISpecificationResult OrderByDescending(Expression> keySelector); 57 | 58 | /// 59 | /// Gets the list of domain objects the specification represents. 60 | /// 61 | IList ToList(); 62 | 63 | /// 64 | /// Gets single domain object the specification represents. 65 | /// 66 | TEntity Single(); 67 | 68 | /// 69 | /// Returns the only element of a sequence, or a default value if the sequence is empty; 70 | /// this method throws an exception if there is more than one element in the sequence. 71 | /// 72 | TEntity SingleOrDefault(); 73 | } 74 | } 75 | -------------------------------------------------------------------------------- /Besnik.GenericRepository/Interfaces/ITransaction.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Besnik.GenericRepository 4 | { 5 | /// 6 | /// Represents transaction in the repository. 7 | /// Don't forget to dispose the transaction when you are done with the transaction. 8 | /// 9 | /// 10 | /// Suggested pattern when working with transaction interface is as following: 11 | /// using ( var unitOfWork = this.UnitOfWorkFactory.BeginUnitOfWork() ) 12 | /// { 13 | /// ICustomerRepository cr = this.CreateCustomerRepository(unitOfWork); 14 | /// 15 | /// using ( var transaction = unitOfWork.BeginTransaction() ) 16 | /// { 17 | /// cr.Insert(customer); 18 | /// 19 | /// transaction.Commit(); 20 | /// } 21 | /// } 22 | /// 23 | /// If you need to work with transaction without using block, don't forget to rollback 24 | /// transaciton is catch block (if possible) and dispose the transaction in finally block: 25 | /// ITransaction transaction = null; 26 | /// try 27 | /// { 28 | /// transaction = unitOfWork.BeginTransaction() 29 | /// cr.Insert(customer); 30 | /// transaction.Commit(); 31 | /// } 32 | /// catch 33 | /// { 34 | /// transaction.Rollback(); 35 | /// throw; 36 | /// } 37 | /// finally 38 | /// { 39 | /// if (transaction != null) { transaction.Dispose(); } 40 | /// } 41 | /// 42 | public interface ITransaction : IDisposable 43 | { 44 | /// 45 | /// Commits the transaction. 46 | /// 47 | void Commit(); 48 | 49 | /// 50 | /// Rollbacks the transaction. 51 | /// 52 | void Rollback(); 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Besnik.GenericRepository/Interfaces/IUnitOfWork.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | 4 | namespace Besnik.GenericRepository 5 | { 6 | /// 7 | /// The interface represents unit of work pattern implementation. 8 | /// 9 | public interface IUnitOfWork : IDisposable 10 | { 11 | /// 12 | /// Flushes content of unit of work to the underlying data storage. Causes unsaved 13 | /// entities to be written to the data storage. 14 | /// 15 | void Flush(); 16 | 17 | /// 18 | /// Begins the transaction. 19 | /// 20 | ITransaction BeginTransaction(); 21 | 22 | /// 23 | /// Ends transaction. 24 | /// Note: suggested pattern to manage a transaction is via *using* construct. 25 | /// You should set input param to null after calling the method. 26 | /// 27 | /// 28 | /// using ( var tnx = uow.BeginTransaction() ) { /* do some work */ } 29 | /// 30 | /// See also interface for more details. 31 | void EndTransaction(ITransaction transaction); 32 | 33 | /// 34 | /// Inserts entity to the storage. 35 | /// 36 | void Insert(TEntity entity) where TEntity : class; 37 | 38 | /// 39 | /// Updates entity in the storage. 40 | /// 41 | void Update(TEntity entity) where TEntity : class; 42 | 43 | /// 44 | /// Deletes entity in the storage. 45 | /// 46 | void Delete(TEntity entity) where TEntity : class; 47 | 48 | /// 49 | /// Gets entity from the storage by it's Id. 50 | /// 51 | TEntity GetById(TPrimaryKey id) where TEntity : class; 52 | 53 | /// 54 | /// Gets all entities of the type from the storage. 55 | /// 56 | IList GetAll() where TEntity : class; 57 | } 58 | } 59 | -------------------------------------------------------------------------------- /Besnik.GenericRepository/Interfaces/IUnitOfWorkConvertor.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | namespace Besnik.GenericRepository 5 | { 6 | /// 7 | /// Helper interface to convert to various data providers. 8 | /// 9 | public interface IUnitOfWorkConvertor 10 | { 11 | /// 12 | /// Gets from given implementation. 13 | /// 14 | IQueryable ToQueryable(IUnitOfWork unitOfWork) where TEntity : class; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /Besnik.GenericRepository/Interfaces/IUnitOfWorkFactory.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace Besnik.GenericRepository 4 | { 5 | /// 6 | /// The interface for wrapps concrete implementation of unit of work pattern. 7 | /// 8 | public interface IUnitOfWorkFactory : IDisposable 9 | { 10 | /// 11 | /// Begins unit of work. 12 | /// 13 | IUnitOfWork BeginUnitOfWork(); 14 | 15 | /// 16 | /// Ends unit of work. 17 | /// 18 | void EndUnitOfWork(IUnitOfWork unitOfWork); 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /Besnik.GenericRepository/Properties/AssemblyInfo.cs: -------------------------------------------------------------------------------- 1 | using System.Reflection; 2 | using System.Runtime.CompilerServices; 3 | using System.Runtime.InteropServices; 4 | 5 | // General Information about an assembly is controlled through the following 6 | // set of attributes. Change these attribute values to modify the information 7 | // associated with an assembly. 8 | [assembly: AssemblyTitle("Besnik.GenericRepository")] 9 | [assembly: AssemblyDescription("")] 10 | [assembly: AssemblyConfiguration("")] 11 | [assembly: AssemblyCompany("")] 12 | [assembly: AssemblyProduct("")] 13 | [assembly: AssemblyCopyright("")] 14 | [assembly: AssemblyTrademark("")] 15 | [assembly: AssemblyCulture("")] 16 | 17 | // Setting ComVisible to false makes the types in this assembly not visible 18 | // to COM components. If you need to access a type in this assembly from 19 | // COM, set the ComVisible attribute to true on that type. 20 | [assembly: ComVisible(false)] 21 | 22 | // The following GUID is for the ID of the typelib if this project is exposed to COM 23 | [assembly: Guid("0003ff1d-3fb3-45f0-b747-617250f2538a")] 24 | 25 | // Version information for an assembly consists of the following four values: 26 | // 27 | // Major Version 28 | // Minor Version 29 | // Build Number 30 | // Revision 31 | // 32 | // You can specify all the values or you can default the Build and Revision Numbers 33 | // by using the '*' as shown below: 34 | // [assembly: AssemblyVersion("1.0.*")] 35 | [assembly: AssemblyVersion("1.1.0.*")] 36 | [assembly: AssemblyFileVersion("1.1.0.0")] 37 | -------------------------------------------------------------------------------- /Besnik.GenericRepository/QueryableSpecification/QueryableSpecification.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Linq; 3 | 4 | namespace Besnik.GenericRepository 5 | { 6 | /// 7 | /// Base class for based specifications. 8 | /// 9 | public abstract class QueryableSpecification : ISpecification 10 | where TEntity : class 11 | { 12 | /// 13 | /// Constructor. 14 | /// 15 | /// Interface provides functionality to convert 16 | /// unit of work to . 17 | public QueryableSpecification(IUnitOfWorkConvertor unitOfWorkConvertor) 18 | { 19 | if (unitOfWorkConvertor == null) 20 | { 21 | throw new ArgumentNullException("unitOfWorkConvertor"); 22 | } 23 | 24 | this.UnitOfWorkConvertor = unitOfWorkConvertor; 25 | } 26 | 27 | /// 28 | /// Gets or sets the queryable instance. 29 | /// 30 | protected IQueryable Queryable { get; set; } 31 | 32 | /// 33 | /// Gets unit of work convertor. 34 | /// 35 | protected IUnitOfWorkConvertor UnitOfWorkConvertor { get; private set; } 36 | 37 | /// 38 | /// Initializes specification from given unit of work. 39 | /// Implementation varies on implementation. 40 | /// 41 | public virtual void Initialize(IUnitOfWork unitOfWork) 42 | { 43 | this.Queryable = this.UnitOfWorkConvertor.ToQueryable(unitOfWork); 44 | } 45 | 46 | /// 47 | /// Returns queryable specification result. 48 | /// 49 | public ISpecificationResult ToResult() 50 | { 51 | return new QueryableSpecificationResult(Queryable); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /Besnik.GenericRepository/QueryableSpecification/QueryableSpecificationResult.cs: -------------------------------------------------------------------------------- 1 | using System.Collections.Generic; 2 | using System.Linq; 3 | using System.Linq.Expressions; 4 | using System; 5 | 6 | namespace Besnik.GenericRepository 7 | { 8 | /// 9 | /// Specification result class contains common functionality for filtering result. 10 | /// 11 | /// Domain entity. 12 | public class QueryableSpecificationResult : ISpecificationResult 13 | where TEntity : class 14 | { 15 | /// 16 | /// Constructor. 17 | /// 18 | public QueryableSpecificationResult(IQueryable queryable) 19 | { 20 | this.Queryable = queryable; 21 | } 22 | 23 | /// 24 | /// Gets or sets IQueryable interface for domain entity. 25 | /// 26 | protected IQueryable Queryable { get; set; } 27 | 28 | /// 29 | /// Takes given count of the records represented by the specification. 30 | /// 31 | public ISpecificationResult Take(int count) 32 | { 33 | this.Queryable = this.Queryable.Take(count); 34 | return this; 35 | } 36 | 37 | /// 38 | /// Executes the specification and query behind it and returns list of records 39 | /// that matches criteria. 40 | /// 41 | public IList ToList() 42 | { 43 | return Queryable.ToList(); 44 | } 45 | 46 | /// 47 | /// Executes the specification and query behind it and returns the only record 48 | /// of a sequence. Throws if there is not exactly one element in the sequence. 49 | /// 50 | public TEntity Single() 51 | { 52 | return Queryable.Single(); 53 | } 54 | 55 | 56 | /// 57 | /// Bypasses a specified number of elements in a sequence and then returns 58 | /// the remaining elements. 59 | /// 60 | public ISpecificationResult Skip(int count) 61 | { 62 | this.Queryable = this.Queryable.Skip(count); 63 | return this; 64 | } 65 | 66 | /// 67 | /// Sorts the elements of a sequence in ascending order according to a key. 68 | /// 69 | public ISpecificationResult OrderByAscending(Expression> keySelector) 70 | { 71 | this.Queryable = this.Queryable.OrderBy(keySelector); 72 | return this; 73 | } 74 | 75 | /// 76 | /// Sorts the elements of a sequence in descending order according to a key. 77 | /// 78 | public ISpecificationResult OrderByDescending(Expression> keySelector) 79 | { 80 | this.Queryable = this.Queryable.OrderByDescending(keySelector); 81 | return this; 82 | } 83 | 84 | /// 85 | /// Returns the only element of a sequence, or a default value if the sequence is empty; 86 | /// this method throws an exception if there is more than one element in the sequence. 87 | /// 88 | public TEntity SingleOrDefault() 89 | { 90 | return Queryable.SingleOrDefault(); 91 | } 92 | } 93 | } 94 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Generic Repository 2 | GenericRepository project is generic implementation of Repository pattern in .NET. 3 | For detailed discussion please see project's wiki pages and especially [Introduction](https://github.com/besnik/generic-repository/wiki/Introduction). 4 | 5 | 6 | # Lightweight 7 | It is lightweight thin layer between domain model and data mappers (e.g. ORMs like NHibernate, Linq2Sql or Entity Framework). The goal is to avoid recreating same repositories over and over again in all projects where repository pattern is used. Designed with respect to DDD (domain driven design). Implements Filter pattern and best used with factory and/or Service locator patter (DI/IoC). I used the name specification, but it turned out to be confusing of other design pattern, so from now on I call it filters. 8 | 9 | Example of usage: 10 | ``` java 11 | var customer = new Customer { Name = "Peter Bondra", Age = 37 }; 12 | var specificationLocator = this.IoC.Resolve(); 13 | 14 | using ( var unitOfWork = this.IoC.Resolve().BeginUnitOfWork() ) 15 | { 16 | ICustomerRepository cr = this.IoC.Resolve(unitOfWork, specificationLocator); 17 | 18 | using ( var transaction = unitOfWork.BeginTransaction() ) 19 | { 20 | cr.Insert(customer); 21 | transaction.Commit(); 22 | } 23 | } 24 | ``` 25 | 26 | # Fluent filter pattern 27 | The generic repository natively supports filter pattern that decouples the filter logic (queries) from the repository. It contains extension point for your custom filters and the filter interface (called specification) shall be implemented using fluent interface pattern. 28 | 29 | Example of fluent filter pattern usage (I call it specification in the code): 30 | ``` java 31 | ICustomerRepository customerRepository = 32 | this.IoC.Resolve(unitOfWork, specificationLocator); 33 | 34 | IList = customerRepository.Specify() 35 | .NameStartsWith("Peter") 36 | .OlderThan(18) 37 | .ToResult() 38 | .Take(3) 39 | .ToList(); 40 | ``` 41 | 42 | # CRUD and DRY 43 | Don't repeat yourself. GenericRepository provides implementation of repository patter, so you can focus on your domain model and business rules, instead of fighting with specific data mapper technology (some knowledge is still required for doing mapping configuration). You can start loading and saving data to the data storage extremly fast. If the Generic repository does not support requested functionalit natively, you can still very easily use underlying data mapper. 44 | 45 | 46 | # Abstraction of data mappers 47 | Nice sideeffect is that it is very easy to switch between several data mappers, for example from Entity Framework to NHibernate and so on. 48 | 49 | # Learning resource 50 | Last but not least: great learning resource. By implementing generic repository with various data mappers, it is very easy to see the design and architecture differences between the libraries. For example, GetById method differs in LinqToSql and NHibernate, because NHibernate accepts type Object as ID, in comparing to LinqToSql that is strongly typed. This small difference makes it more complex to implement base class for LinqToSql repositories as you can see in the sources. Note that IGenericRepository and it's methods are all strongly typed, the difference is just under the hood. So that was one example. Other can be found in the source codes. 51 | 52 | 53 | # Unit tested 54 | Ships with unit tests. 55 | Note: when running tests, make sure to adapt connection strings in config directory (or data mapper configuration). There is a plan to make default data provider some file based database like sql ce, so the unit tests would work on of the box. 56 | 57 | # Well documented 58 | Source codes fully documented. 59 | External documentation and pattern explanation can be found at my [blog](http://besnikgeek.blogspot.com/search/label/generic%20repository). 60 | 61 | # Feedback 62 | I would really like to get feedback what features are missing for your project. The layer is very thin and it is easy to extend and add new features. Contributors are welcome. 63 | 64 | # Dependencies 65 | The solution file is for Visual Studio 2010 and projects are targeting CLR 4.0 (.NET 4.0); 66 | If there is a need for older version of CLR, it is no problem to build it for CLR 2.0 (.NET 2.0, 3.0, 3.5). Some of the linked libraries may still be compiled for CLR 2.0, the plan is to migrate everything to CLR 4.0. 67 | Unit tests are using NUnit and Mock frameworks. 68 | 69 | 70 | # Licence 71 | Open to use in commerce and non-commerce projects. 72 | 73 | # Supported data mappers 74 | * NHibernate 75 | * Linq2Sql 76 | * Entity Framework 77 | 78 | Plan is to implement suppport for 79 | * NoSql data mappers like Mongo, RavenDb, CouchDB, etc. 80 | * Anything the community requests 81 | 82 | You can always implement IGenericRepository interface for your favourite data mapper and push the implementation. -------------------------------------------------------------------------------- /packages/Autofac.2.6.1.841/Autofac.2.6.1.841.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/Autofac.2.6.1.841/Autofac.2.6.1.841.nupkg -------------------------------------------------------------------------------- /packages/Autofac.2.6.1.841/lib/NET35/Autofac.Configuration.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/Autofac.2.6.1.841/lib/NET35/Autofac.Configuration.dll -------------------------------------------------------------------------------- /packages/Autofac.2.6.1.841/lib/NET35/Autofac.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/Autofac.2.6.1.841/lib/NET35/Autofac.dll -------------------------------------------------------------------------------- /packages/Autofac.2.6.1.841/lib/NET40/Autofac.Configuration.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/Autofac.2.6.1.841/lib/NET40/Autofac.Configuration.dll -------------------------------------------------------------------------------- /packages/Autofac.2.6.1.841/lib/NET40/Autofac.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/Autofac.2.6.1.841/lib/NET40/Autofac.dll -------------------------------------------------------------------------------- /packages/Autofac.2.6.1.841/lib/SL3-WP/Autofac.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/Autofac.2.6.1.841/lib/SL3-WP/Autofac.dll -------------------------------------------------------------------------------- /packages/Autofac.2.6.1.841/lib/SL4-WindowsPhone/Autofac.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/Autofac.2.6.1.841/lib/SL4-WindowsPhone/Autofac.dll -------------------------------------------------------------------------------- /packages/Autofac.2.6.1.841/lib/SL4-WindowsPhone71/Autofac.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/Autofac.2.6.1.841/lib/SL4-WindowsPhone71/Autofac.dll -------------------------------------------------------------------------------- /packages/Autofac.2.6.1.841/lib/SL4/Autofac.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/Autofac.2.6.1.841/lib/SL4/Autofac.dll -------------------------------------------------------------------------------- /packages/EntityFramework.4.3.1/Content/App.config.transform: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /packages/EntityFramework.4.3.1/Content/Web.config.transform: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /packages/EntityFramework.4.3.1/EntityFramework.4.3.1.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/EntityFramework.4.3.1/EntityFramework.4.3.1.nupkg -------------------------------------------------------------------------------- /packages/EntityFramework.4.3.1/lib/net40/EntityFramework.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/EntityFramework.4.3.1/lib/net40/EntityFramework.dll -------------------------------------------------------------------------------- /packages/EntityFramework.4.3.1/tools/EF4.3on.NET4.5Readme.txt: -------------------------------------------------------------------------------- 1 | ----------------------------------------------------------------------------------------- 2 | Entity Framework 5 Recommended for .NET Framework 4.5 Projects 3 | ----------------------------------------------------------------------------------------- 4 | 5 | 6 | You have installed EF 4.3 in a project that targets .NET Framework 4.5. 7 | 8 | There are some known issues using EF 4.x in a .NET 4.5 project. 9 | 10 | 11 | We recommend installing a pre-release version of EF 5, which is designed to work with .NET 4.5 12 | 13 | 1) Open package manager console 14 | Tools -> Library Package Manager -> Package Manager Console 15 | 16 | 2) Use the following command to install the latest pre-release package 17 | Install-Package EntityFramework -IncludePreRelease 18 | 19 | 20 | 21 | ----------------------------------------------------------------------------------------- 22 | Known Issues with Entity Framework 4.x and .NET Framework 4.5 23 | ----------------------------------------------------------------------------------------- 24 | 25 | Entity Framework 4.1 thru 4.3 included additional data annotations in the 26 | System.ComponentModel.DataAnnotations namespace in the EntityFramework assembly. 27 | In .NET 4.5 these annotations were moved to be part of the .NET Framework in the 28 | System.ComponentModel.DataAnnotations.Schema namespace of the 29 | System.ComponentModel.DataAnnotations.dll assembly. If you are using EF 4.x and targeting 30 | .NET 4.5 this results in two data annotations with the same name in different assemblies. 31 | Because the annotations in the .NET Framework are in a different namespace we were not 32 | able to use type forwarding to avoid this conflict. 33 | 34 | It is possible to use EF 4.x on .NET 4.5 but we recommend using the latest pre-release 35 | version of EF 5. If you are not using the affected data annotations there is no impact 36 | on your code. If you are using the data annotations in a C# project you can use the extern 37 | modifier to ensure your code uses the annotations from EntityFramework.dll 38 | (http://msdn.microsoft.com/en-us/library/e59b22c5(v=VS.80).aspx). If you use the new 39 | annotations from the System.ComponentModel.DataAnnotations.dll assembly in .NET 4.5 40 | they will not be processed by Code First. 41 | 42 | The affected annotations are: 43 | - Column 44 | - ComplexType 45 | - DatabaseGenerated 46 | - DatabaseGeneratedOption 47 | - ForeignKey 48 | - InverseProperty 49 | - MaxLength 50 | - MinLength 51 | - NotMapped 52 | - Table 53 | -------------------------------------------------------------------------------- /packages/EntityFramework.4.3.1/tools/EntityFramework.PowerShell.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/EntityFramework.4.3.1/tools/EntityFramework.PowerShell.dll -------------------------------------------------------------------------------- /packages/EntityFramework.4.3.1/tools/EntityFramework.psd1: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/EntityFramework.4.3.1/tools/EntityFramework.psd1 -------------------------------------------------------------------------------- /packages/EntityFramework.4.3.1/tools/EntityFramework.psm1: -------------------------------------------------------------------------------- 1 | # Copyright (c) Microsoft Corporation. All rights reserved. 2 | 3 | $InitialDatabase = '0' 4 | 5 | $installPath = $args[0] 6 | $knownExceptions = @( 7 | 'System.Data.Entity.Migrations.Infrastructure.MigrationsException', 8 | 'System.Data.Entity.Migrations.Infrastructure.AutomaticMigrationsDisabledException', 9 | 'System.Data.Entity.Migrations.Infrastructure.AutomaticDataLossException' 10 | ) 11 | 12 | <# 13 | .SYNOPSIS 14 | Enables Code First Migrations in a project. 15 | 16 | .DESCRIPTION 17 | Enables Migrations by scaffolding a migrations configuration class in the project. If the 18 | target database was created by an initializer, an initial migration will be created (unless 19 | automatic migrations are enabled via the EnableAutomaticMigrations parameter). 20 | 21 | .PARAMETER EnableAutomaticMigrations 22 | Specifies whether automatic migrations will be enabled in the scaffolded migrations configuration. 23 | If ommitted, automatic migrations will be disabled. 24 | 25 | .PARAMETER ProjectName 26 | Specifies the project that the scaffolded migrations configuration class will 27 | be added to. If omitted, the default project selected in package manager 28 | console is used. 29 | 30 | .PARAMETER Force 31 | Specifies that the migrations configuration be overwritten when running more 32 | than once for a given project. 33 | #> 34 | function Enable-Migrations 35 | { 36 | [CmdletBinding(DefaultParameterSetName = 'ProjectName')] 37 | param ( 38 | [alias("Auto")] 39 | [switch] $EnableAutomaticMigrations, 40 | [string] $ProjectName, 41 | [switch] $Force 42 | ) 43 | 44 | try 45 | { 46 | $commands = New-MigrationsCommandsNoConfiguration $ProjectName 47 | $commands.EnableMigrations($EnableAutomaticMigrations, $Force) 48 | } 49 | catch [Exception] 50 | { 51 | $exception = $_.Exception 52 | $exceptionType = $exception.GetType() 53 | 54 | if ($exceptionType.FullName -eq 'System.Data.Entity.Migrations.Design.ToolingException') 55 | { 56 | if ($knownExceptions -notcontains $exception.InnerType) 57 | { 58 | Write-Host $exception.InnerStackTrace 59 | } 60 | } 61 | elseif (!(Test-TypeInherits $exceptionType 'System.Data.Entity.Migrations.Infrastructure.MigrationsException')) 62 | { 63 | Write-Host $exception 64 | } 65 | 66 | throw $exception.Message 67 | } 68 | } 69 | 70 | <# 71 | .SYNOPSIS 72 | Scaffolds a migration script for any pending model changes. 73 | 74 | .DESCRIPTION 75 | Scaffolds a new migration script and adds it to the project. 76 | 77 | .PARAMETER Name 78 | Specifies the name of the custom script. 79 | 80 | .PARAMETER Force 81 | Specifies that the migration user code be overwritten when re-scaffolding an 82 | existing migration. 83 | 84 | .PARAMETER ProjectName 85 | Specifies the project that contains the migration configuration type to be 86 | used. If ommitted, the default project selected in package manager console 87 | is used. 88 | 89 | .PARAMETER StartUpProjectName 90 | Specifies the configuration file to use for named connection strings. If 91 | omitted, the specified project's configuration file is used. 92 | 93 | .PARAMETER ConfigurationTypeName 94 | Specifies the migrations configuration to use. If omitted, migrations will 95 | attempt to locate a single migrations configuration type in the target 96 | project. 97 | 98 | .PARAMETER ConnectionStringName 99 | Specifies the name of a connection string to use from the application's 100 | configuration file. 101 | 102 | .PARAMETER ConnectionString 103 | Specifies the the connection string to use. If omitted, the context's 104 | default connection will be used. 105 | 106 | .PARAMETER ConnectionProviderName 107 | Specifies the provider invariant name of the connection string. 108 | 109 | .PARAMETER IgnoreChanges 110 | Scaffolds an empty migration ignoring any pending changes detected in the current model. 111 | This can be used to create an initial, empty migration to enable Migrations for an existing 112 | database. N.B. Doing this assumes that the target database schema is compatible with the 113 | current model. 114 | 115 | #> 116 | function Add-Migration 117 | { 118 | [CmdletBinding(DefaultParameterSetName = 'ConnectionStringName')] 119 | param ( 120 | [parameter(Position = 0, 121 | Mandatory = $true)] 122 | [string] $Name, 123 | [switch] $Force, 124 | [string] $ProjectName, 125 | [string] $StartUpProjectName, 126 | [string] $ConfigurationTypeName, 127 | [parameter(ParameterSetName = 'ConnectionStringName')] 128 | [string] $ConnectionStringName, 129 | [parameter(ParameterSetName = 'ConnectionStringAndProviderName', 130 | Mandatory = $true)] 131 | [string] $ConnectionString, 132 | [parameter(ParameterSetName = 'ConnectionStringAndProviderName', 133 | Mandatory = $true)] 134 | [string] $ConnectionProviderName, 135 | [switch] $IgnoreChanges) 136 | 137 | try 138 | { 139 | $commands = New-MigrationsCommands $ProjectName $StartUpProjectName $ConfigurationTypeName $ConnectionStringName $ConnectionString $ConnectionProviderName 140 | $commands.AddMigration($Name, $Force, $IgnoreChanges) 141 | } 142 | catch [Exception] 143 | { 144 | $exception = $_.Exception 145 | $exceptionType = $exception.GetType() 146 | 147 | if ($exceptionType.FullName -eq 'System.Data.Entity.Migrations.Design.ToolingException') 148 | { 149 | if ($knownExceptions -notcontains $exception.InnerType) 150 | { 151 | Write-Host $exception.InnerStackTrace 152 | } 153 | } 154 | elseif (!(Test-TypeInherits $exceptionType 'System.Data.Entity.Migrations.Infrastructure.MigrationsException')) 155 | { 156 | Write-Host $exception 157 | } 158 | 159 | throw $exception.Message 160 | } 161 | } 162 | 163 | <# 164 | .SYNOPSIS 165 | Applies any pending migrations to the database. 166 | 167 | .DESCRIPTION 168 | Updates the database to the current model by applying pending migrations. 169 | 170 | .PARAMETER SourceMigration 171 | Only valid with -Script. Specifies the name of a particular migration to use 172 | as the update's starting point. If ommitted, the last applied migration in 173 | the database will be used. 174 | 175 | .PARAMETER TargetMigration 176 | Specifies the name of a particular migration to update the database to. If 177 | ommitted, the current model will be used. 178 | 179 | .PARAMETER Script 180 | Generate a SQL script rather than executing the pending changes directly. 181 | 182 | .PARAMETER Force 183 | Specifies that data loss is acceptable during automatic migration of the 184 | database. 185 | 186 | .PARAMETER ProjectName 187 | Specifies the project that contains the migration configuration type to be 188 | used. If ommitted, the default project selected in package manager console 189 | is used. 190 | 191 | .PARAMETER StartUpProjectName 192 | Specifies the configuration file to use for named connection strings. If 193 | omitted, the specified project's configuration file is used. 194 | 195 | .PARAMETER ConfigurationTypeName 196 | Specifies the migrations configuration to use. If omitted, migrations will 197 | attempt to locate a single migrations configuration type in the target 198 | project. 199 | 200 | .PARAMETER ConnectionStringName 201 | Specifies the name of a connection string to use from the application's 202 | configuration file. 203 | 204 | .PARAMETER ConnectionString 205 | Specifies the the connection string to use. If omitted, the context's 206 | default connection will be used. 207 | 208 | .PARAMETER ConnectionProviderName 209 | Specifies the provider invariant name of the connection string. 210 | #> 211 | function Update-Database 212 | { 213 | [CmdletBinding(DefaultParameterSetName = 'ConnectionStringName')] 214 | param ( 215 | [string] $SourceMigration, 216 | [string] $TargetMigration, 217 | [switch] $Script, 218 | [switch] $Force, 219 | [string] $ProjectName, 220 | [string] $StartUpProjectName, 221 | [string] $ConfigurationTypeName, 222 | [parameter(ParameterSetName = 'ConnectionStringName')] 223 | [string] $ConnectionStringName, 224 | [parameter(ParameterSetName = 'ConnectionStringAndProviderName', 225 | Mandatory = $true)] 226 | [string] $ConnectionString, 227 | [parameter(ParameterSetName = 'ConnectionStringAndProviderName', 228 | Mandatory = $true)] 229 | [string] $ConnectionProviderName) 230 | 231 | # TODO: If possible, convert this to a ParameterSet 232 | if ($SourceMigration -and !$script) 233 | { 234 | throw '-SourceMigration can only be specified with -Script.' 235 | } 236 | 237 | try 238 | { 239 | $commands = New-MigrationsCommands $ProjectName $StartUpProjectName $ConfigurationTypeName $ConnectionStringName $ConnectionString $ConnectionProviderName 240 | $commands.UpdateDatabase($SourceMigration, $TargetMigration, $Script, $Force) 241 | } 242 | catch [Exception] 243 | { 244 | $exception = $_.Exception 245 | $exceptionType = $exception.GetType() 246 | 247 | if ($exceptionType.FullName -eq 'System.Data.Entity.Migrations.Design.ToolingException') 248 | { 249 | if ($knownExceptions -notcontains $exception.InnerType) 250 | { 251 | Write-Host $exception.InnerStackTrace 252 | } 253 | } 254 | elseif (!(Test-TypeInherits $exceptionType 'System.Data.Entity.Migrations.Infrastructure.MigrationsException')) 255 | { 256 | Write-Host $exception 257 | } 258 | 259 | throw $exception.Message 260 | } 261 | } 262 | 263 | <# 264 | .SYNOPSIS 265 | Displays the migrations that have been applied to the target database. 266 | 267 | .DESCRIPTION 268 | Displays the migrations that have been applied to the target database. 269 | 270 | .PARAMETER ProjectName 271 | Specifies the project that contains the migration configuration type to be 272 | used. If ommitted, the default project selected in package manager console 273 | is used. 274 | 275 | .PARAMETER StartUpProjectName 276 | Specifies the configuration file to use for named connection strings. If 277 | omitted, the specified project's configuration file is used. 278 | 279 | .PARAMETER ConfigurationTypeName 280 | Specifies the migrations configuration to use. If omitted, migrations will 281 | attempt to locate a single migrations configuration type in the target 282 | project. 283 | 284 | .PARAMETER ConnectionStringName 285 | Specifies the name of a connection string to use from the application's 286 | configuration file. 287 | 288 | .PARAMETER ConnectionString 289 | Specifies the the connection string to use. If omitted, the context's 290 | default connection will be used. 291 | 292 | .PARAMETER ConnectionProviderName 293 | Specifies the provider invariant name of the connection string. 294 | #> 295 | function Get-Migrations 296 | { 297 | [CmdletBinding(DefaultParameterSetName = 'ConnectionStringName')] 298 | param ( 299 | [string] $ProjectName, 300 | [string] $StartUpProjectName, 301 | [string] $ConfigurationTypeName, 302 | [parameter(ParameterSetName = 'ConnectionStringName')] 303 | [string] $ConnectionStringName, 304 | [parameter(ParameterSetName = 'ConnectionStringAndProviderName', 305 | Mandatory = $true)] 306 | [string] $ConnectionString, 307 | [parameter(ParameterSetName = 'ConnectionStringAndProviderName', 308 | Mandatory = $true)] 309 | [string] $ConnectionProviderName) 310 | 311 | try 312 | { 313 | $commands = New-MigrationsCommands $ProjectName $StartUpProjectName $ConfigurationTypeName $ConnectionStringName $ConnectionString $ConnectionProviderName 314 | $commands.GetMigrations() 315 | } 316 | catch [Exception] 317 | { 318 | $exception = $_.Exception 319 | $exceptionType = $exception.GetType() 320 | 321 | if ($exceptionType.FullName -eq 'System.Data.Entity.Migrations.Design.ToolingException') 322 | { 323 | if ($knownExceptions -notcontains $exception.InnerType) 324 | { 325 | Write-Host $exception.InnerStackTrace 326 | } 327 | } 328 | elseif (!(Test-TypeInherits $exceptionType 'System.Data.Entity.Migrations.Infrastructure.MigrationsException')) 329 | { 330 | Write-Host $exception 331 | } 332 | 333 | throw $exception.Message 334 | } 335 | } 336 | 337 | function New-MigrationsCommandsNoConfiguration($ProjectName) 338 | { 339 | $project = Get-MigrationsProject $ProjectName 340 | 341 | Build-Project $project 342 | 343 | Load-EntityFramework 344 | 345 | try 346 | { 347 | return New-Object 'System.Data.Entity.Migrations.MigrationsCommands' @( 348 | $project, 349 | $project, 350 | $null, 351 | $null, 352 | $null, 353 | $null, 354 | $PSCmdlet ) 355 | } 356 | catch [System.Management.Automation.MethodInvocationException] 357 | { 358 | throw $_.Exception.InnerException 359 | } 360 | } 361 | 362 | function New-MigrationsCommands($ProjectName, $StartUpProjectName, $ConfigurationTypeName, $ConnectionStringName, $ConnectionString, $ConnectionProviderName) 363 | { 364 | $project = Get-MigrationsProject $ProjectName 365 | $startUpProject = Get-MigrationsStartUpProject $StartUpProjectName 366 | 367 | Build-Project $project 368 | Build-Project $startUpProject 369 | 370 | Load-EntityFramework 371 | 372 | try 373 | { 374 | return New-Object 'System.Data.Entity.Migrations.MigrationsCommands' @( 375 | $project, 376 | $startUpProject, 377 | $ConfigurationTypeName, 378 | $ConnectionStringName, 379 | $ConnectionString, 380 | $ConnectionProviderName, 381 | $PSCmdlet ) 382 | } 383 | catch [System.Management.Automation.MethodInvocationException] 384 | { 385 | throw $_.Exception.InnerException 386 | } 387 | } 388 | 389 | function Get-MigrationsProject($name) 390 | { 391 | if ($name) 392 | { 393 | return Get-SingleProject $name 394 | } 395 | 396 | $project = Get-Project 397 | 398 | Write-Verbose ('Using NuGet project ''' + $project.Name + '''.') 399 | 400 | return $project 401 | } 402 | 403 | function Get-MigrationsStartUpProject($name) 404 | { 405 | if ($name) 406 | { 407 | return Get-SingleProject $name 408 | } 409 | 410 | $startupProjectPaths = $DTE.Solution.SolutionBuild.StartupProjects 411 | 412 | if (!$startupProjectPaths) 413 | { 414 | throw 'No start-up project found. Please use the -StartupProject parameter.' 415 | } 416 | if ($startupProjectPaths.Length -gt 1) 417 | { 418 | throw 'More than one start-up project found. Please use the -StartUpProject parameter.' 419 | } 420 | 421 | $startupProjectPath = $startupProjectPaths[0] 422 | 423 | if (!(Split-Path -IsAbsolute $startupProjectPath)) 424 | { 425 | $solutionPath = Split-Path $DTE.Solution.Properties.Item('Path').Value 426 | $startupProjectPath = Join-Path $solutionPath $startupProjectPath -Resolve 427 | } 428 | 429 | $startupProject = $DTE.Solution.Projects | ?{ 430 | $fullName = $_.FullName 431 | 432 | if ($fullName -and $fullName.EndsWith('\')) 433 | { 434 | $fullName = $fullName.Substring(0, $fullName.Length - 1) 435 | } 436 | 437 | return $fullName -eq $startupProjectPath 438 | } 439 | 440 | Write-Verbose ('Using StartUp project ''' + $startupProject.Name + '''.') 441 | 442 | return $startupProject 443 | } 444 | 445 | function Get-SingleProject($name) 446 | { 447 | $project = Get-Project $name 448 | 449 | if ($project -is [array]) 450 | { 451 | throw "More than one project '$name' was found. Specify the full name of the one to use." 452 | } 453 | 454 | return $project 455 | } 456 | 457 | function Load-EntityFramework() 458 | { 459 | [System.AppDomain]::CurrentDomain.SetShadowCopyFiles() 460 | [System.Reflection.Assembly]::LoadFrom((Join-Path $installPath 'lib\net40\EntityFramework.dll')) | Out-Null 461 | [System.Reflection.Assembly]::LoadFrom((Join-Path $installPath 'tools\EntityFramework.PowerShell.dll')) | Out-Null 462 | } 463 | 464 | function Build-Project($project) 465 | { 466 | $configuration = $DTE.Solution.SolutionBuild.ActiveConfiguration.Name 467 | 468 | $DTE.Solution.SolutionBuild.BuildProject($configuration, $project.UniqueName, $true) 469 | 470 | if ($DTE.Solution.SolutionBuild.LastBuildInfo) 471 | { 472 | throw 'The project ''' + $project.Name + ''' failed to build.' 473 | } 474 | } 475 | 476 | function Test-TypeInherits($type, $baseTypeName) 477 | { 478 | if ($type.FullName -eq $baseTypeName) 479 | { 480 | return $true 481 | } 482 | 483 | $baseType = $type.BaseType 484 | 485 | if ($baseType) 486 | { 487 | return Test-TypeInherits $baseType $baseTypeName 488 | } 489 | 490 | return $false 491 | } 492 | 493 | Export-ModuleMember @( 'Enable-Migrations', 'Add-Migration', 'Update-Database', 'Get-Migrations' ) -Variable 'InitialDatabase' 494 | -------------------------------------------------------------------------------- /packages/EntityFramework.4.3.1/tools/init.ps1: -------------------------------------------------------------------------------- 1 | param($installPath, $toolsPath, $package, $project) 2 | 3 | if ([System.AppDomain]::CurrentDomain.GetAssemblies() | ?{ $_.GetName().Name -eq 'EntityFramework' }) 4 | { 5 | Write-Warning 'There is already a version of EntityFramework.dll loaded. You may need to restart Visual Studio for the commands to work properly.' 6 | } 7 | 8 | if (Get-Module | ?{ $_.Name -eq 'EntityFramework' }) 9 | { 10 | Remove-Module 'EntityFramework' 11 | } 12 | 13 | Import-Module (Join-Path $toolsPath 'EntityFramework.psd1') -ArgumentList $installPath 14 | -------------------------------------------------------------------------------- /packages/EntityFramework.4.3.1/tools/install.ps1: -------------------------------------------------------------------------------- 1 | param($installPath, $toolsPath, $package, $project) 2 | 3 | $invoker = @" 4 | public class ConnectionFactoryConfiguratorInvoker 5 | { 6 | public static void Invoke(string assemblyPath, object project) 7 | { 8 | var appDomain = System.AppDomain.CreateDomain( 9 | "EntityFramework.PowerShell", 10 | null, 11 | new System.AppDomainSetup { ShadowCopyFiles = "true" }); 12 | 13 | appDomain.CreateInstanceFrom( 14 | assemblyPath, 15 | "System.Data.Entity.ConnectionFactoryConfig.ConnectionFactoryConfigurator", 16 | false, 17 | 0, 18 | null, 19 | new object[] { project }, 20 | null, 21 | null); 22 | 23 | System.AppDomain.Unload(appDomain); 24 | } 25 | } 26 | "@ 27 | 28 | $version = (new-object System.Runtime.Versioning.FrameworkName($project.Properties.Item("TargetFrameworkMoniker").Value)).Version 29 | 30 | if ($version -ge (new-object System.Version(4, 5))) 31 | { 32 | $dte.ItemOperations.OpenFile((Join-Path $toolsPath 'EF4.3on.NET4.5Readme.txt')) 33 | } 34 | 35 | Add-Type -TypeDefinition $invoker 36 | [ConnectionFactoryConfiguratorInvoker]::Invoke((Join-Path $toolsPath "EntityFramework.PowerShell.dll"), $project) 37 | -------------------------------------------------------------------------------- /packages/EntityFramework.4.3.1/tools/migrate.exe: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/EntityFramework.4.3.1/tools/migrate.exe -------------------------------------------------------------------------------- /packages/Iesi.Collections.3.2.0.4000/Iesi.Collections.3.2.0.4000.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/Iesi.Collections.3.2.0.4000/Iesi.Collections.3.2.0.4000.nupkg -------------------------------------------------------------------------------- /packages/Iesi.Collections.3.2.0.4000/lib/Net35/Iesi.Collections.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/Iesi.Collections.3.2.0.4000/lib/Net35/Iesi.Collections.dll -------------------------------------------------------------------------------- /packages/NHibernate.3.3.0.4000/ConfigurationTemplates/FireBird.cfg.xml: -------------------------------------------------------------------------------- 1 | 2 | 12 | 17 | 18 | 19 | NHibernate.Driver.FirebirdClientDriver 20 | 21 | Server=localhost; 22 | Database=C:\nhibernate.fdb; 23 | User=SYSDBA;Password=masterkey 24 | 25 | false 26 | NHibernate.Dialect.FirebirdDialect 27 | 60 28 | true 1, false 0, yes 1, no 0 29 | 30 | 31 | -------------------------------------------------------------------------------- /packages/NHibernate.3.3.0.4000/ConfigurationTemplates/MSSQL.cfg.xml: -------------------------------------------------------------------------------- 1 |  2 | 7 | 8 | 9 | 10 | NHibernate.Driver.SqlClientDriver 11 | 12 | Server=(local);initial catalog=nhibernate;Integrated Security=SSPI 13 | 14 | NHibernate.Dialect.MsSql2008Dialect 15 | 16 | -------------------------------------------------------------------------------- /packages/NHibernate.3.3.0.4000/ConfigurationTemplates/MySql.cfg.xml: -------------------------------------------------------------------------------- 1 |  2 | 7 | 8 | 9 | 10 | NHibernate.Driver.MySqlDataDriver 11 | 12 | Database=test;Data Source=someip;User Id=blah;Password=blah 13 | 14 | NHibernate.Dialect.MySQLDialect 15 | 16 | -------------------------------------------------------------------------------- /packages/NHibernate.3.3.0.4000/ConfigurationTemplates/Oracle.cfg.xml: -------------------------------------------------------------------------------- 1 |  2 | 7 | 8 | 9 | 10 | NHibernate.Driver.OracleClientDriver 11 | 12 | User ID=nhibernate;Password=nhibernate;Data Source=localhost 13 | 14 | false 15 | NHibernate.Dialect.OracleDialect 16 | true 1, false 0, yes 'Y', no 'N' 17 | 18 | -------------------------------------------------------------------------------- /packages/NHibernate.3.3.0.4000/ConfigurationTemplates/PostgreSQL.cfg.xml: -------------------------------------------------------------------------------- 1 |  2 | 7 | 8 | 9 | NHibernate.Driver.NpgsqlDriver 10 | 11 | Server=localhost;Database=nhibernate;User ID=nhibernate;Password=nhibernate; 12 | 13 | NHibernate.Dialect.PostgreSQL82Dialect 14 | 15 | -------------------------------------------------------------------------------- /packages/NHibernate.3.3.0.4000/ConfigurationTemplates/SQLite.cfg.xml: -------------------------------------------------------------------------------- 1 |  2 | 7 | 8 | 9 | NHibernate.Driver.SQLite20Driver 10 | 11 | Data Source=nhibernate.db 12 | 13 | NHibernate.Dialect.SQLiteDialect 14 | 15 | -------------------------------------------------------------------------------- /packages/NHibernate.3.3.0.4000/ConfigurationTemplates/SybaseASE.cfg.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | NHibernate.Driver.SybaseAseClientDriver 10 | 11 | Data Source=10.0.0.1;Port=5000;Database=nhibernate;User ID=nhibernate;Password=password 12 | 13 | NHibernate.Dialect.SybaseASE15Dialect 14 | true=1;false=0 15 | 16 | -------------------------------------------------------------------------------- /packages/NHibernate.3.3.0.4000/ConfigurationTemplates/SybaseSQLAnywhere.cfg.xml: -------------------------------------------------------------------------------- 1 | 2 | 7 | 8 | 9 | NHibernate.Driver.SybaseSQLAnywhereDriver 10 | 11 | UID=DBA;PWD=sql;Server=localhost;DBN=nhibernate;DBF=c:\nhibernate.db;ASTOP=No 12 | 13 | NHibernate.Dialect.SybaseSQLAnywhere12Dialect 14 | true=1;false=0 15 | 16 | -------------------------------------------------------------------------------- /packages/NHibernate.3.3.0.4000/NHibernate.3.3.0.4000.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/NHibernate.3.3.0.4000/NHibernate.3.3.0.4000.nupkg -------------------------------------------------------------------------------- /packages/NHibernate.3.3.0.4000/NHibernate.readme.html: -------------------------------------------------------------------------------- 1 |

Welcome to NHibernate

2 | 3 |

NHibernate is a mature, open source object-relational mapper for the .NET framework. It is actively developed, 4 | fully featured and used in thousands of successful projects.

5 | 6 |

The NHibernate community website - http://www.nhforge.org - has a range of resources to help you get started, 7 | including wikis, blogs and reference documentation.

8 | 9 |

Latest Version

10 | 11 |

The quickest way to get the latest release of NHibernate is to add it to your project using 12 | NuGet (http://nuget.org/List/Packages/NHibernate).

13 | 14 |

Alternatively binaries are available from SourceForge at http://sourceforge.net/projects/nhibernate.

15 | 16 |

You are encouraged to review the release notes (releasenotes.txt), particularly when upgrading to a 17 | later version. The release notes will generally document any breaking changes.

18 | 19 |

Community Forums

20 | 21 |

There are two official NHibernate community forums:

22 | 23 | 27 | 28 |

Bug Reports

29 | 30 |

If you find any bugs, please report them using the JIRA bug tracker. A 31 | test-case that demonstrates the issue is usually required. Instructions on providing a test-case 32 | can be found here.

33 | 34 |

Licenses

35 | 36 |

This software is distributed under the terms of the Free Software Foundation Lesser GNU Public License (LGPL), version 2.1 (see lgpl.txt).

37 | 38 |

Credits

39 | 40 |

Many thanks to the following individuals, organisations and projects whose work is so important to the success 41 | of NHibernate (in no particular order):

42 | 43 | -------------------------------------------------------------------------------- /packages/NHibernate.3.3.0.4000/NHibernate.releasenotes.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/NHibernate.3.3.0.4000/NHibernate.releasenotes.txt -------------------------------------------------------------------------------- /packages/NHibernate.3.3.0.4000/lib/Net35/NHibernate.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/NHibernate.3.3.0.4000/lib/Net35/NHibernate.dll -------------------------------------------------------------------------------- /packages/NHibernate.3.3.0.4000/nhibernate-configuration.xsd: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | -- This schema was automatically generated by Syntext Dtd2Schema and changed for NH use -- 5 | -- conversion tool (from file: hibernate-configuration-3.0.dtd) -- 6 | -- Copyright (C) 2002, 2003 Syntext Inc. See http://www.syntext.com for updates. -- 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | There are 3 default short-cut values 17 | - lcg : default for .NET2.0 and higher. 18 | - codedom : CodeDOM-based bytecode provider (mostly for .NET1.1). 19 | - null : Disable the reflection optimization completely. 20 | In addition you can specify the AssemblyQualifiedName of your custom bytecode-provider (implementation of IBytecodeProvider). 21 | Note: the bytecode-provider will be tooks in account only when specified in the app.config or web.config. 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | There are 3 possible combinations of mapping attributes 57 | 1 - resource & assembly: NHibernate will read the mapping resource from the specified assembly 58 | 2 - file only: NHibernate will read the mapping from the file. 59 | 3 - assembly only: NHibernate will find all the resources ending in hbm.xml from the assembly. 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | -------------------------------------------------------------------------------- /packages/NHibernate.Linq.1.0/NHibernate.Linq.1.0.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/NHibernate.Linq.1.0/NHibernate.Linq.1.0.nupkg -------------------------------------------------------------------------------- /packages/NHibernate.Linq.1.0/lib/NHibernate.Linq.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/NHibernate.Linq.1.0/lib/NHibernate.Linq.dll -------------------------------------------------------------------------------- /packages/NUnit.2.6.0.12054/NUnit.2.6.0.12054.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/NUnit.2.6.0.12054/NUnit.2.6.0.12054.nupkg -------------------------------------------------------------------------------- /packages/NUnit.2.6.0.12054/lib/nunit.framework.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/NUnit.2.6.0.12054/lib/nunit.framework.dll -------------------------------------------------------------------------------- /packages/NUnit.2.6.0.12054/license.txt: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/NUnit.2.6.0.12054/license.txt -------------------------------------------------------------------------------- /packages/System.Data.SQLite.1.0.80.0/System.Data.SQLite.1.0.80.0.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/System.Data.SQLite.1.0.80.0/System.Data.SQLite.1.0.80.0.nupkg -------------------------------------------------------------------------------- /packages/System.Data.SQLite.1.0.80.0/lib/net20/System.Data.SQLite.Linq.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/System.Data.SQLite.1.0.80.0/lib/net20/System.Data.SQLite.Linq.dll -------------------------------------------------------------------------------- /packages/System.Data.SQLite.1.0.80.0/lib/net20/System.Data.SQLite.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/System.Data.SQLite.1.0.80.0/lib/net20/System.Data.SQLite.dll -------------------------------------------------------------------------------- /packages/System.Data.SQLite.1.0.80.0/lib/net40/System.Data.SQLite.Linq.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/System.Data.SQLite.1.0.80.0/lib/net40/System.Data.SQLite.Linq.dll -------------------------------------------------------------------------------- /packages/System.Data.SQLite.1.0.80.0/lib/net40/System.Data.SQLite.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/System.Data.SQLite.1.0.80.0/lib/net40/System.Data.SQLite.dll -------------------------------------------------------------------------------- /packages/log4net.2.0.0/lib/net10-full/log4net.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/log4net.2.0.0/lib/net10-full/log4net.dll -------------------------------------------------------------------------------- /packages/log4net.2.0.0/lib/net11-full/log4net.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/log4net.2.0.0/lib/net11-full/log4net.dll -------------------------------------------------------------------------------- /packages/log4net.2.0.0/lib/net20-cf/log4net.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/log4net.2.0.0/lib/net20-cf/log4net.dll -------------------------------------------------------------------------------- /packages/log4net.2.0.0/lib/net20-full/log4net.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/log4net.2.0.0/lib/net20-full/log4net.dll -------------------------------------------------------------------------------- /packages/log4net.2.0.0/lib/net35-client/log4net.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/log4net.2.0.0/lib/net35-client/log4net.dll -------------------------------------------------------------------------------- /packages/log4net.2.0.0/lib/net35-full/log4net.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/log4net.2.0.0/lib/net35-full/log4net.dll -------------------------------------------------------------------------------- /packages/log4net.2.0.0/lib/net40-client/log4net.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/log4net.2.0.0/lib/net40-client/log4net.dll -------------------------------------------------------------------------------- /packages/log4net.2.0.0/lib/net40-full/log4net.dll: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/log4net.2.0.0/lib/net40-full/log4net.dll -------------------------------------------------------------------------------- /packages/log4net.2.0.0/log4net.2.0.0.nupkg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/besnik/generic-repository/0a5407ca84cdec49a57fc55da8d323bf5495edc5/packages/log4net.2.0.0/log4net.2.0.0.nupkg -------------------------------------------------------------------------------- /packages/repositories.config: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | 6 | 7 | 8 | --------------------------------------------------------------------------------