Created
August 2, 2012 16:02
-
-
Save JasonOffutt/3238169 to your computer and use it in GitHub Desktop.
Proposal for adding dependency injection of IRepository<T> into Rock
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<configuration> | |
<appSettings> | |
<clear/> | |
<add key="RepositoryType" value="Rock.Tests.Fakes.FakeAttributeRepository,Rock.Tests"/> | |
</appSettings> | |
</configuration |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Page : ModelWithAttributes<Page>, IExportable | |
{ | |
// ... | |
// Here's a very simplified/non-recursive example of usage that causes | |
// a problem. ModelWithAttributes<Page> has a Service<Page> that ultimately | |
// would be instantiated as an EFRepository<Page> rather than something that | |
// can be controlled from outside (e.g. config settings or dependency injection). | |
public object ExportObject() | |
{ | |
return this.ToDynamic(); | |
} | |
public string ExportJson() | |
{ | |
return this.ExportObject.ToJson(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class PageTests | |
{ | |
public class TheExportJsonMethod | |
{ | |
// Here's an example of a unit test that should be isolated from | |
// the database. This test should be able to run without having | |
// to rely on any external component, like a database, web service, etc. | |
[Fact] | |
public void ShouldNotBeEmpty() | |
{ | |
var page = new Page() { Name = "FooPage" }; | |
var result = page.ExportJson(); | |
Assert.NotEmpty(result); | |
} | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Here's the proposed implementation of RepositoryFactory. Using config settings | |
// is probably the quickest and easiest solution. I've also implemented something | |
// similar in Grassroots that uses MEF. Both approaches add a bit of overhead, but | |
// should give us a lot of flexibility. And due to how heavily things get cached, | |
// we shouldn't notice much of a performance hit. | |
public static class RepositoryFactory | |
{ | |
public static IRepository<T> FindRepository<T>() where T : class | |
{ | |
// First, check the config file to see if anything special needs to be done... | |
var repositoryType = ConfigurationManager.AppSettings["RepositoryType"]; | |
// If not, load the usual EFRepository... | |
if (string.IsNullOrEmpty(repositoryType)) | |
{ | |
return new EFRepository<T>(); | |
} | |
// Otherwise create an instance of the type defined in the config file. | |
var setting = repositoryType.Split( new[] { ',' } ); | |
var classPath = setting[0].Trim(); | |
var assemblyName = setting[1].Trim(); | |
return (IRepository<T>) Activator.CreateInstance( assemblyName, classPath ).Unwrap(); | |
} | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
public class Service<T> | |
{ | |
private IRepository<T> _repository; | |
protected IRepository<T> | |
{ | |
get { return _repository; } | |
} | |
// This line is giving me a little grief. There is a hard dependency on | |
// EFRepository, even though there's a constructor that accepts an | |
// IRepository<T> arg, there's no good way for to control how it gets | |
// instantiated. | |
public Service<T>() // : this(new EFRepository<T>()) | |
{ | |
_repository = RepositoryFactory.FindRepository<T>(); | |
} | |
public Service<T>(IRepository<T> repository) | |
{ | |
_repository = repository; | |
} | |
// ... | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment