雖然有助於OSS project工作,但我正在運行TypeLoadException。我正在創建一個縫,開發人員可以注入他們自己的Repository類來刪除EF上的具體依賴關係,這樣我就可以隔離我的新代碼並運行一些測試。動態實例化一個嵌套類型爲arg的對象時引發TypeLoadException
看來,針對具有嵌套類型arg的類型運行Activator.CreateInstance()
會在運行時引發一個扳手。我以前使用過這種模式很多次,但這次不同的是我使用它來動態注入一個通用的Repository模式實現。這個問題似乎與該類型的arg有關。我目前難住,所以任何幫助將不勝感激。
這裏是我得到的錯誤:
System.TypeLoadException: Could not load type 'Rock.Tests.Fakes.FakeRepository' from assembly 'Rock.Tests, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null'.
at System.Reflection.RuntimeAssembly.GetType(RuntimeAssembly assembly, String name, Boolean throwOnError, Boolean ignoreCase, ObjectHandleOnStack type)
at System.Reflection.RuntimeAssembly.GetType(String name, Boolean throwOnError, Boolean ignoreCase)
at System.Activator.CreateInstance(String assemblyName, String typeName, Boolean ignoreCase, BindingFlags bindingAttr, Binder binder, Object[] args, CultureInfo culture, Object[] activationAttributes, Evidence securityInfo, ref StackCrawlMark stackMark)
at System.Activator.CreateInstance(String assemblyName, String typeName)
at Rock.Data.RepositoryFactory`1.FindRepository() in RepositoryFactory.cs: line 30
at Rock.Data.Service`1..ctor() in Service.cs: line 34
at Rock.Core.AttributeService..ctor()
at Rock.Attribute.Helper.LoadAttributes(IHasAttributes item) in Helper.cs: line 165
at Rock.Data.ModelWithAttributes`1.get_Attributes() in ModelWithAttributes.cs: line 38
at Rock.CMS.Page.MapPagesRecursive(Page page) in Page.cs: line 422
at Rock.CMS.Page.ExportObject() in Page.cs: line 410
at Rock.Tests.CMS.PageTests.TheExportObjectMethod.ShouldCopyPropertiesOfDTO() in PageTests.cs: line 16
下面是一些有關(註釋)代碼從Rock.Data命名空間中的片段:
IRepository.cs
public interface IRepository<T> where T : class
{
// Very basic CRUD repository contract...
}
個EFRepository.cs
public class EFRepository<T> where T : Model<T>
{
// Concrete implementation of IRepository<T> specific to Entity Framework 4.3
}
Service.cs
public class Service<T> where T : Model<T>
{
private readonly IRepository<T> _repository;
// Inside this constructor are my changes...
public Service() // : this(new EFRepository<T>())
{
// Instead of hard-coding the use of EFRepository here, I
// thought it might be worthwhile to add a call out to a
// factory method implementation.
var factory = new RepositoryFactory<T>();
_repository = factory.FindRepository();
}
// This constructor never really appears to be called.
// From my test code's entry point, there's no way for me to
// explicitly call this constructor, hence the factory implemenation.
public Service(IRepository<T> repository)
{
_repository = repository;
}
}
RepositoryFactory.cs
// Here's my quick/dirty factory method implementation to try to generically
// instantiate an IRepository of my choosing for testing purposes...
public class RepositoryFactory<T> where T : Model<T>
{
public IRepository<T> FindRepository()
{
var repositoryTypeSetting = ConfiguraitonManager.AppSettings["RepositoryType"];
if (string.IsNullOrEmpty(repositoryTypeSetting))
{
return new EFRepository<T>();
}
var settingArray = repositoryTypeSetting.Split(new[] { ',' });
// I'm aware that Trim() is superfluous here, but this will be part of a development
// framework, so I'm trying to take whitespace/developer error into account.
var className = settingArray[0].Trim();
var assemblyName = settingArray[1].Trim();
// I've tried with and without Unwrap(), the exception originates from Activator.CreateInstance()
return (IRepository<T>) Activator.CreateInstance(assemblyName, className).Unwrap();
}
}
下面是一些假冒的對象和測試代碼片段我的m在我單獨的Rock.Tests項目中使用......個
FakeRepository.cs
// Basic fake/stub implementation
public class FakeRepository<T> : IRepository<T> where T : Model<T>
{
// Nothing here yet other than `throw new NotImplementedException()` for each method in the contract
// We never make it here...
}
PageTests.cs
// Very basic XUnit test example...
public class PageTests
{
public class TheExportMethod
{
[Fact]
public void ShouldNotBeEmpty()
{
var page = new Page { Name = "FooPage" };
var result = page.Export();
Assert.NotEmpty(result);
}
}
}
的App.config
<configuration>
<appSettings>
<clear/>
<add key="RepositoryType" value="Rock.Tests.Fakes.FakeRepository,Rock.Tests"/>
</appSettings>
</configuration>
Hopef這是涵蓋它非常徹底。提前致謝!
所有的代碼真的有關嗎?你能以某種方式縮短這個嗎?大約一半的時候,我的眼睛眯起來。 – MikeKulls 2012-08-16 21:59:34
大多數情況下,他們都是。主要是爲了幫助說明所涉及的限制。好的東西更接近底部(RepositoryFactory類)。 – JasonOffutt 2012-08-17 07:38:25