Skip to content

Commit

Permalink
Ioc and IRepository<T> bug
Browse files Browse the repository at this point in the history
Fixes SharpRepository#88

I needed to add a specific repository factory override for a single
generic type instead of passing typeof(int) into the existing one which
in turn returns an IRepository<T,int> which the Ioc can't cast as an
IRepository<T>
  • Loading branch information
Jeff Treuting committed Jul 24, 2013
1 parent 97e978e commit 569c694
Show file tree
Hide file tree
Showing 18 changed files with 141 additions and 36 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ public CacheConfigRepositoryFactory(IRepositoryConfiguration config)
{
}

public override IRepository<T> GetInstance<T>()
{
return new CacheRepository<T>(RepositoryConfiguration["prefix"]);
}

public override IRepository<T, TKey> GetInstance<T, TKey>()
{
return new CacheRepository<T, TKey>(RepositoryConfiguration["prefix"]);
Expand Down
5 changes: 5 additions & 0 deletions SharpRepository.Db4oRepository/Db4oConfigRepositoryFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ public Db4oConfigRepositoryFactory(IRepositoryConfiguration config)
{
}

public override IRepository<T> GetInstance<T>()
{
throw new NotImplementedException("Db4oRepository does not support using IRepository<T> directly to reference a IRepository<T, string>");
}

public override IRepository<T, TKey> GetInstance<T, TKey>()
{
// check for required parameters
Expand Down
5 changes: 5 additions & 0 deletions SharpRepository.Ef5Repository/Ef5ConfigRepositoryFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,11 @@ public Ef5ConfigRepositoryFactory(IRepositoryConfiguration config)
{
}

public override IRepository<T> GetInstance<T>()
{
return new Ef5Repository<T>(GetDbContext());
}

public override IRepository<T, TKey> GetInstance<T, TKey>()
{
return new Ef5Repository<T, TKey>(GetDbContext());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,11 @@ public InMemoryConfigRepositoryFactory(IRepositoryConfiguration config)
{
}

public override IRepository<T> GetInstance<T>()
{
return new InMemoryRepository<T>();
}

public override IRepository<T, TKey> GetInstance<T, TKey>()
{
return new InMemoryRepository<T, TKey>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ public MongoDbConfigRepositoryFactory(IRepositoryConfiguration config)
{
}

public override IRepository<T> GetInstance<T>()
{
throw new NotImplementedException("MongoDbRepository does not support using IRepository<T> directly to reference a IRepository<T, string>");
}

public override IRepository<T, TKey> GetInstance<T, TKey>()
{
// check for required parameters
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,11 @@ public RavenDbConfigRepositoryFactory(IRepositoryConfiguration config)
{
}

public override IRepository<T> GetInstance<T>()
{
throw new NotImplementedException("RavenDbRepository does not support using IRepository<T> directly to reference a IRepository<T, string>");
}

public override IRepository<T, TKey> GetInstance<T, TKey>()
{
var documentStore =new DocumentStore();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ namespace SharpRepository.Repository.Configuration
{
public interface IConfigRepositoryFactory
{
IRepository<T> GetInstance<T>() where T : class, new();
IRepository<T, TKey> GetInstance<T, TKey>() where T : class, new();
ICompoundKeyRepository<T, TKey, TKey2> GetInstance<T, TKey, TKey2>() where T : class, new();
}
Expand All @@ -16,6 +17,7 @@ protected ConfigRepositoryFactory(IRepositoryConfiguration config)
RepositoryConfiguration = config;
}

public abstract IRepository<T> GetInstance<T>() where T : class, new();
public abstract IRepository<T, TKey> GetInstance<T, TKey>() where T : class, new();
public abstract ICompoundKeyRepository<T, TKey, TKey2> GetInstance<T, TKey, TKey2>() where T : class, new();
}
Expand Down
36 changes: 36 additions & 0 deletions SharpRepository.Repository/Configuration/ConfigurationHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,42 @@ public static void CheckForInterface(Type type, Type interfaceType)
throw new System.Configuration.ConfigurationErrorsException("The type " + type.AssemblyQualifiedName + " must implement " + interfaceType.AssemblyQualifiedName);
}

public static IRepository<T> GetInstance<T>(ISharpRepositoryConfiguration configuration, string repositoryName) where T : class, new()
{
if (!configuration.HasRepository)
{
throw new Exception("There are no repositories configured");
}

var repositoryConfiguration = configuration.GetRepository(repositoryName);
var repository = repositoryConfiguration.GetInstance<T>();

if (repository == null)
return null;

var strategyConfiguration = configuration.GetCachingStrategy(repositoryConfiguration.CachingStrategy);
if (strategyConfiguration == null)
{
return repository;
}

var cachingStrategy = strategyConfiguration.GetInstance<T, int>();
if (cachingStrategy == null)
{
return repository;
}

var providerConfiguration = configuration.GetCachingProvider(repositoryConfiguration.CachingProvider);
if (providerConfiguration != null)
{
cachingStrategy.CachingProvider = providerConfiguration.GetInstance();
}

repository.CachingStrategy = cachingStrategy;

return repository;
}

public static IRepository<T, TKey> GetInstance<T, TKey>(ISharpRepositoryConfiguration configuration, string repositoryName) where T : class, new()
{
if (!configuration.HasRepository)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ public interface IRepositoryConfiguration
IDictionary<string, string> Attributes { get; set; }
string this[string key] { get; }

IRepository<T> GetInstance<T>() where T : class, new();
IRepository<T, TKey> GetInstance<T, TKey>() where T : class, new();
ICompoundKeyRepository<T, TKey, TKey2> GetInstance<T, TKey, TKey2>() where T : class, new();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ public interface ISharpRepositoryConfiguration
string DefaultCachingProvider { get; set; }
ICachingProviderConfiguration GetCachingProvider(string providerName);

IRepository<T> GetInstance<T>(string repositoryName = null) where T : class, new();
IRepository<T, TKey> GetInstance<T, TKey>(string repositoryName = null) where T : class, new();
ICompoundKeyRepository<T, TKey, TKey2> GetInstance<T, TKey, TKey2>(string repositoryName = null) where T : class, new();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,14 @@ public Type Factory

public IDictionary<string, string> Attributes { get; set; }

public IRepository<T> GetInstance<T>() where T : class, new()
{
// load up the factory if it exists and use it
var factory = (IConfigRepositoryFactory)Activator.CreateInstance(Factory, this);

return factory.GetInstance<T>();
}

public IRepository<T, TKey> GetInstance<T, TKey>() where T : class, new()
{
// load up the factory if it exists and use it
Expand Down
8 changes: 8 additions & 0 deletions SharpRepository.Repository/Configuration/RepositoryElement.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,14 @@ public string CachingProvider
set { base["cachingProvider"] = value; }
}

public IRepository<T> GetInstance<T>() where T : class, new()
{
// load up the factory if it exists and use it
var factory = (IConfigRepositoryFactory) Activator.CreateInstance(Factory, this);

return factory.GetInstance<T>();
}

public IRepository<T, TKey> GetInstance<T, TKey>() where T : class, new()
{
// load up the factory if it exists and use it
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,11 @@ public void AddCachingProvider(string name, Type factory, IDictionary<string, st
});
}

public IRepository<T> GetInstance<T>(string repositoryName = null) where T : class, new()
{
return ConfigurationHelper.GetInstance<T>(this, repositoryName);
}

public IRepository<T, TKey> GetInstance<T, TKey>(string repositoryName = null) where T : class, new()
{
return ConfigurationHelper.GetInstance<T, TKey>(this, repositoryName);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -138,6 +138,11 @@ public ICachingProviderConfiguration GetCachingProvider(string providerName)
return providerConfiguration;
}

public IRepository<T> GetInstance<T>(string repositoryName = null) where T : class, new()
{
return ConfigurationHelper.GetInstance<T>(this, repositoryName);
}

public IRepository<T, TKey> GetInstance<T, TKey>(string repositoryName = null) where T : class, new()
{
return ConfigurationHelper.GetInstance<T, TKey>(this, repositoryName);
Expand Down
17 changes: 12 additions & 5 deletions SharpRepository.Repository/RepositoryFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ public static class RepositoryFactory

public static object GetInstance(Type entityType, string repositoryName = null)
{
return GetInstance(entityType, typeof(int), repositoryName);
return GetInstance(entityType, DefaultConfigSection, repositoryName);
}

public static object GetInstance(Type entityType, Type keyType, string repositoryName = null)
Expand All @@ -47,7 +47,7 @@ public static object GetInstance(Type entityType, Type keyType, string repositor

public static object GetInstance(Type entityType, string configSection, string repositoryName)
{
return GetInstance(entityType, typeof(int), configSection, repositoryName);
return GetInstance(entityType, GetConfiguration(configSection), repositoryName);
}

public static object GetInstance(Type entityType, Type keyType, string configSection, string repositoryName)
Expand All @@ -66,10 +66,17 @@ public static object GetInstance(Type entityType, Type keyType, string configSec
return configuration.GetInstance<T, TKey>(repositoryName);
}

public static object GetInstance(Type entityType, ISharpRepositoryConfiguration configuration,
string repositoryName = null)
public static object GetInstance(Type entityType, ISharpRepositoryConfiguration configuration, string repositoryName = null)
{
return GetInstance(entityType, typeof (int), configuration, repositoryName);
if (String.IsNullOrEmpty(repositoryName))
{
// if no specific repository is provided then check to see if the SharpRepositoryConfigurationAttribute is used
repositoryName = GetAttributeRepositoryName(entityType);
}

var method = typeof(ISharpRepositoryConfiguration).GetMethods().First(m => m.Name == "GetInstance" && m.ReturnType.Name == "IRepository`1");
var genericMethod = method.MakeGenericMethod(entityType);
return genericMethod.Invoke(configuration, new object[] { repositoryName });
}

public static object GetInstance(Type entityType, Type keyType, ISharpRepositoryConfiguration configuration, string repositoryName = null)
Expand Down
40 changes: 9 additions & 31 deletions SharpRepository.Tests.Integration/App.config
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,8 @@
<configuration>
<configSections>
<!-- Raven Db Section-->
<sectionGroup name="sharpRepository" type="SharpRepository.Repository.Configuration.SharpRepositorySectionGroup, SharpRepository.Repository">
<sectionGroup name="repositories" type="SharpRepository.Repository.Configuration.RepositoriesSectionGroup, SharpRepository.Repository">
<section name="default" type="SharpRepository.Repository.Configuration.DefaultSection, SharpRepository.Repository" />
<section name="inMemoryRepository" type="SharpRepository.InMemoryRepository.Config, SharpRepository.InMemoryRepository" />
<!-- <section name="ef5Repository" type="SharpRepository.Ef5Repository.Config, SharpRepository.Ef5Repository" />-->
<section name="efRepository" type="SharpRepository.EfRepository.Config, SharpRepository.EfRepository" />
<section name="ravenDbRepository" type="SharpRepository.RavenDbRepository.Config, SharpRepository.RavenDbRepository" />
<section name="mongoDbRepository" type="SharpRepository.MongoDbRepository.Config, SharpRepository.MongoDbRepository" />
</sectionGroup>
</sectionGroup>
<sectionGroup name="efRepositoryTest" type="SharpRepository.Repository.Configuration.SharpRepositorySectionGroup, SharpRepository.Repository">
<sectionGroup name="repositories" type="SharpRepository.Repository.Configuration.RepositoriesSectionGroup, SharpRepository.Repository">
<section name="default" type="SharpRepository.Repository.Configuration.DefaultSection, SharpRepository.Repository" />
<section name="inMemoryRepository" type="SharpRepository.InMemoryRepository.Config, SharpRepository.InMemoryRepository" />
<!-- <section name="ef5Repository" type="SharpRepository.Ef5Repository.Config, SharpRepository.Ef5Repository" />-->
<section name="efRepository" type="SharpRepository.EfRepository.Config, SharpRepository.EfRepository" />
<section name="ravenDbRepository" type="SharpRepository.RavenDbRepository.Config, SharpRepository.RavenDbRepository" />
<section name="mongoDbRepository" type="SharpRepository.MongoDbRepository.Config, SharpRepository.MongoDbRepository" />
</sectionGroup>
</sectionGroup>
<section name="sharpRepository" type="SharpRepository.Repository.Configuration.SharpRepositorySection, SharpRepository.Repository" />

<!-- For more information on Entity Framework configuration, visit http://go.microsoft.com/fwlink/?LinkID=237468 -->
<section name="entityFramework" type="System.Data.Entity.Internal.ConfigFile.EntityFrameworkSection, EntityFramework, Version=4.4.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089" requirePermission="false" />
</configSections>
Expand All @@ -30,19 +12,15 @@
</connectionStrings>
<sharpRepository>
<repositories>
<default name="ravenDb" />
<!-- <ef5Repository name="ef5" connectionString="Ef5ConnectionString" dbContextType=""/>-->
<inMemoryRepository name="inMemory" />
<ravenDbRepository name="ravenDb" url="http://localhost:8080" />
<mongoDbRepository name="mongoDb" />
<repository name="ef5Repository" connectionString="Ef5ConnectionString" factory="SharpRepository.Ef5Repository.Ef5ConfigRepositoryFactory, SharpRepository.Ef5Repository" />
</repositories>
</sharpRepository>
<efRepositoryTest>
<repositories>
<default name="ef" />
<efRepository name="ef" connectionString="Ef5ConnectionString" dbContextType="SharpRepository.Tests.Integration.TestObjects.TestObjectEntities, SharpRepository.Tests.Integration" />
</repositories>
</efRepositoryTest>
<!-- <efRepositoryTest>-->
<!-- <repositories>-->
<!-- <default name="ef" />-->
<!-- <efRepository name="ef" connectionString="Ef5ConnectionString" dbContextType="SharpRepository.Tests.Integration.TestObjects.TestObjectEntities, SharpRepository.Tests.Integration" />-->
<!-- </repositories>-->
<!-- </efRepositoryTest>-->
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using NUnit.Framework;
using SharpRepository.Ef5Repository;
using SharpRepository.Ioc.StructureMap;
using SharpRepository.Repository;
using SharpRepository.Repository.Ioc;
using SharpRepository.Tests.Integration.Data;
using SharpRepository.Tests.Integration.TestObjects;
Expand Down Expand Up @@ -71,6 +72,18 @@ public void Ef5ConfigRepositoryFactory_Using_Ioc_Should_Share_DbContext()

dbContext1.ShouldEqual(dbContext2);
}

[Test]
public void Ioc_For_IRepository_T_Should_Not_Error()
{
var repos = ObjectFactory.GetInstance<IRepository<ContactType>>();
}

[Test]
public void Ioc_For_IRepository_T_TKey_Should_Not_Error()
{
var repos = ObjectFactory.GetInstance<IRepository<ContactType, int>>();
}
}

public class StructureMapRegistry : Registry
Expand Down
11 changes: 11 additions & 0 deletions SharpRepository.XmlRepository/XmlConfigRepositoryFactory.cs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,17 @@ public XmlConfigRepositoryFactory(IRepositoryConfiguration config)
{
}

public override IRepository<T> GetInstance<T>()
{
// check for required parameters
if (String.IsNullOrEmpty(RepositoryConfiguration["directory"]))
{
throw new ConfigurationErrorsException("The directory attribute is required in order to use the XmlRepository via the configuration file.");
}

return new XmlRepository<T>(RepositoryConfiguration["directory"]);
}

public override IRepository<T, TKey> GetInstance<T, TKey>()
{
// check for required parameters
Expand Down

0 comments on commit 569c694

Please sign in to comment.