Yesterday, I was trying to make a simple test class work in VS2012. I did not know what exactly was wrong. It was the first project when I tried to glue together Entity Framework with repository pattern and Ninject as IoC container. Because of the fact that this was the first time for a solution like that, I was sure that it was me, or rather the source of my problem was indeed my code. But let's not skip ahead.
So when I managed to translate adding EF classes to Unity from here: IoC: using EntityFramework.Patterns with Unity 2.1 into Ninject language, I got an error like this from VS (when I tried to run the test case):
Result Message: Unable to create instance of class UnitTest. Error:
System.IO.FileLoadException: Could not load file or assembly 'EntityFramework,
Version=4.3.1.0, Culture=neutral, PublicKeyToken=b77a5c561934e089' or one of its
dependencies. The located assembly's manifest definition does not
match the assembly reference. (Exception from HRESULT: 0x80131040).
Result StackTrace:
at System.Signature.GetSignature(Void* pCorSig, Int32 cCorSig, RuntimeFieldHandleInternal
fieldHandle, IRuntimeMethodInfo methodHandle, RuntimeType declaringType)
at System.Signature..ctor(IRuntimeMethodInfo methodHandle, RuntimeType declaringType)
at System.Reflection.RuntimeConstructorInfo.GetParametersNoCopy()
at System.Reflection.RuntimeConstructorInfo.GetParameters()
at Ninject.Injection.DynamicMethodInjectorFactory.EmitLoadMethodArguments(ILGenerator il,
MethodBase targetMethod) in
c:\Projects\Ninject\ninject\src\Ninject\Injection\DynamicMethodInjectorFactory.cs:line 115
at Ninject.Injection.DynamicMethodInjectorFactory.Create(ConstructorInfo constructor)
in c:\Projects\Ninject\ninject\src\Ninject\Injection\DynamicMethodInjectorFactory.cs:line 40
at Ninject.Planning.Strategies.ConstructorReflectionStrategy.Execute(IPlan plan) in
c:\Projects\Ninject\ninject\src\Ninject\Planning\Strategies\
ConstructorReflectionStrategy.cs:line 67
at Ninject.Planning.Planner.<>c__DisplayClass1.<CreateNewPlan>b__0(IPlanningStrategy s)
in c:\Projects\Ninject\ninject\src\Ninject\Planning\Planner.cs:line 109
at Ninject.Infrastructure.Language.ExtensionsForIEnumerableOfT.Map[T](IEnumerable`1 series,
Action`1 action) in c:\Projects\Ninject\ninject\src\Ninject\
Infrastructure\Language\ExtensionsForIEnumerableOfT.cs:line 32
at Ninject.Planning.Planner.CreateNewPlan(Type type) in
c:\Projects\Ninject\ninject\src\Ninject\Planning\Planner.cs:line 109
at Ninject.Planning.Planner.GetPlan(Type type) in
c:\Projects\Ninject\ninject\src\Ninject\Planning\Planner.cs:line 71
at Ninject.Activation.Providers.StandardProvider.Create(IContext context)
in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 77
at Ninject.Activation.Context.Resolve() in
c:\Projects\Ninject\ninject\src\Ninject\Activation\Context.cs:line 157
at Ninject.KernelBase.<>c__DisplayClass10.<Resolve>b__c(IBinding binding)
in c:\Projects\Ninject\ninject\src\Ninject\KernelBase.cs:line 386
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Linq.Enumerable.SingleOrDefault[TSource](IEnumerable`1 source)
at Ninject.Planning.Targets.Target`1.GetValue(Type service, IContext parent)
in c:\Projects\Ninject\ninject\src\Ninject\Planning\Targets\Target.cs:line 197
at Ninject.Planning.Targets.Target`1.ResolveWithin(IContext parent)
in c:\Projects\Ninject\ninject\src\Ninject\Planning\Targets\Target.cs:line 165
at Ninject.Activation.Providers.StandardProvider.GetValue(IContext context, ITarget target)
in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 114
at Ninject.Activation.Providers.StandardProvider.<>c__DisplayClass4.<Create>b__2(ITarget target)
in c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 96
at System.Linq.Enumerable.WhereSelectArrayIterator`2.MoveNext()
at System.Linq.Buffer`1..ctor(IEnumerable`1 source)
at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source)
at Ninject.Activation.Providers.StandardProvider.Create(IContext context) in
c:\Projects\Ninject\ninject\src\Ninject\Activation\Providers\StandardProvider.cs:line 96
at Ninject.Activation.Context.Resolve() in
c:\Projects\Ninject\ninject\src\Ninject\Activation\Context.cs:line 157
at Ninject.KernelBase.<>c__DisplayClass10.<Resolve>b__c(IBinding binding)
in c:\Projects\Ninject\ninject\src\Ninject\KernelBase.cs:line 386
at System.Linq.Enumerable.WhereSelectEnumerableIterator`2.MoveNext()
at System.Linq.Enumerable.<CastIterator>d__b1`1.MoveNext()
at System.Linq.Enumerable.Single[TSource](IEnumerable`1 source)
at Ninject.ResolutionExtensions.Get[T](IResolutionRoot root, IParameter[]
parameters) in c:\Projects\Ninject\ninject\src\Ninject\Syntax\ResolutionExtensions.cs:line 37
at UnitTest..ctor()
So my first thought was: heck, I probably did something wrong and it is not so easy (Ninject registrations of components is really easy, you should try yourself). But I cannot find any references to that version of EF anywhere in my project. In fact, I did not add them myself, everything was done by NuGet, so it should work, right? Yes. It should and it was working because:
- Registration of classes from EntityFramework.dll was working perfectly.
- Registration of classes from EntityFramework.Patterns.dll was not working at all.
- When I added console project registration of both types from both assemblies was working without problems.
So the problem was with EntityFramework.Patterns.dll, its internal reference to older version of EF (I was using 5.0 version). Another problem was with assembly redirecting from older version of EF to newer 5.0. In console project section in app.config:
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="EntityFramework"
publicKeyToken="b77a5c561934e089" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-5.0.0.0" newVersion="5.0.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
was doing what it was supposed to, forcing application to use 5.0 version despite internal reference to version 4.3.1 inside EntityFramework.Patterns.dll. So maybe in test, it is not present. Nope it was. Maybe configuration is not copied into Debug dir? Nope. Maybe it is named wrong? Nope. At this moment, I had to take a few minutes off.
I was thinking: everything is as it is supposed to be. Assemblies, references, redirecting, configuration. So... maybe test environment is not starting correctly? Maybe it is ignoring that part of app.config. When I was adding NuGet packages on the same day, I noticed update for VS. Why not try that? Few clicks, about 1 hour and restart of VS after I tried again. Guess what? It worked!
So it was a bug with Visual Studio. I was glad that it was over and a little disappointed for a few hours that I lost. But it was at least one step closer in the right direction.
So if you encounter a problem like that, try to update VS 2012 with Update 2. It should work!