2012-05-15 22 views
10

मैं कारखाना बनाने के लिए निनजेक्ट 3 के साथ निनजेक्ट 3 का उपयोग कर रहा हूं। फैक्ट्री को प्रदान की गई स्ट्रिंग के आधार पर विभिन्न प्रकार के IFoo बनाता है। मुझे पासिंग यूनिट टेस्ट मिला है, लेकिन विचित्र रूप से, केवल रिशेर्पर टेस्ट रनर में। एनसीआरंच परीक्षण धावक में यह विफल रहता है। क्या यह एक एनसीआरंच कॉन्फ़िगरेशन मुद्दा है, या क्या मुझे कोड बदलने की ज़रूरत है?रिजर्वर यूनिट परीक्षणों में निंजा टॉफैक्ट्री काम करता है, लेकिन एनसीआरंच

इंटरफ़ेस:

public interface IFooFactory 
{ 
    IFoo CreateFoo(string name); 
} 

Ninject बाइंडिंग:

kernel.Bind<IFooFactory>().ToFactory(() => new UseFirstParameterAsNameInstanceProvider()); 
kernel.Bind<IFoo>().To<BarFoo>().Named("Bar"); 

परीक्षण:

[Test] 
public void CanCreateFooTest() 
{ 
    var factory = (IFooFactory) Kernel.GetService(typeof(IFooFactory)); 
    var bar = factory.CreateFoo("Bar"); 
    Assert.AreEqual(typeof(BarFoo), bar.GetType()); 
} 

और NCrunch अपवाद:

System.Reflection.TargetInvocationException : Exception has been thrown by the target of an invocation. 
    ----> Ninject.ActivationException : Error activating IInterceptor using conditional implicit self-binding of IInterceptor 
Provider returned null. 
Activation path: 
    2) Injection of dependency IInterceptor into parameter of constructor of type IFooFactoryProxy 
    1) Request for IFooFactory 

Suggestions: 
    1) Ensure that the provider handles creation requests properly. 

    at System.RuntimeMethodHandle._InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, SignatureStruct& sig, MethodAttributes methodAttributes, RuntimeType typeOwner) 
    at System.RuntimeMethodHandle.InvokeMethodFast(IRuntimeMethodInfo method, Object target, Object[] arguments, Signature sig, MethodAttributes methodAttributes, RuntimeType typeOwner) 
    at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture, Boolean skipVisibilityChecks) 
    at System.Reflection.RuntimeMethodInfo.Invoke(Object obj, BindingFlags invokeAttr, Binder binder, Object[] parameters, CultureInfo culture) 
    at Ninject.Infrastructure.Language.ExtensionsForIEnumerable.ToArraySlow(IEnumerable series, Type elementType) in c:\Projects\Ninject\ninject\src\Ninject\Infrastructure\Language\ExtensionsForIEnumerable.cs:line 29 
    at Ninject.Planning.Targets.Target`1.ResolveWithin(IContext parent) in c:\Projects\Ninject\ninject\src\Ninject\Planning\Targets\Target.cs:line 149 
    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 95 
    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.Single[TSource](IEnumerable`1 source) 
    at Ninject.KernelBase.System.IServiceProvider.GetService(Type service) in c:\Projects\Ninject\ninject\src\Ninject\KernelBase.cs:line 553 
    at FooProject.Tests.CanCreateFooTest() in C:\Projects\FooProject ... 
--ActivationException 
    at Ninject.Activation.Context.Resolve() in c:\Projects\Ninject\ninject\src\Ninject\Activation\Context.cs:line 165 
    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.WhereSelectListIterator`2.MoveNext() 
    at System.Linq.Enumerable.<CastIterator>d__b1`1.MoveNext() 
    at System.Linq.Buffer`1..ctor(IEnumerable`1 source) 
    at System.Linq.Enumerable.ToArray[TSource](IEnumerable`1 source) 

उत्तर

6

यहाँ कोड है कि NCrunch साथ काम करता है:

 var kernel = new StandardKernel(); 
     kernel.Bind<IFooFactory>().ToFactory(() => new UseFirstParameterAsNameInstanceProvider()); 
     kernel.Bind<IFoo>().To<BarFoo>().Named("Bar"); 
     kernel.Load<FuncModule>(); 

     var factory = kernel.Get<IFooFactory>(); 
     var bar = factory.CreateFoo("Bar"); 
     Assert.Equal(typeof(BarFoo), bar.GetType()); 

अद्यतन

यह महान काम करता है, और NCrunch को ठीक कर लेगा। हालांकि, रिशेर्पर शिकायत करता है कि इसे दो बार लोड किया गया है। वैकल्पिक हल:

#if NCRUNCH 
     Kernel.Load<FuncModule>(); 
    #endif 
+3

मैं यह बेहतर है, लेकिन जब तक Ninject EnsureLoaded की तरह कुछ प्रदान करता है का दावा नहीं करेगा , #if (यदि आप एक अलग दृष्टिकोण चाहते हैं) का विकल्प यह देखने के लिए जांच कर रहा है कि यह कर्नेल के माध्यम से पहले ही लोड हो चुका है। हैस मॉड्यूल (टाइपऑफ (FuncModule)। FullName) –

+0

हमने एक ऐसी समस्या में एक ही समस्या को मारा जहां हम गतिशील रूप से निकालें मुख्य exe में एम्बेडेड संसाधनों से सभी असेंबली (निंजा सहित)। यह समाधान यहां भी काम करता है (मैन्युअल रूप से 'FuncModule' लोड हो रहा है)। हमारे मामले में, हमने इसे @ जेम्समैनिंग के समाधान के साथ तय किया क्योंकि यह कई स्थानों पर पहले से निर्मित डीएलएल है। –

4

उस testRunner के साथ चलते समय FuncModule लोड नहीं होता है। यह तब होता है जब निष्पादित प्रक्रिया की स्टार्टअप निर्देशिका में एक्सटेंशन की प्रतिलिपि नहीं बनाई जाती है।

मैं एनसीआरंच नहीं करता हूं। तो मैं आपको नहीं बता सकता कि यह क्या कर रहा है। लेकिन सबसे अधिक संभावना है कि यह आर # परीक्षण धावक की तुलना में विधानसभाओं को एक अलग तरीके से कॉपी करता है। आप एक्सटेंशन को मैन्युअल रूप से लोड कर सकते हैं लेकिन यह हैक की तरह लगता है।

8

इकाई परीक्षण पुस्तकालय के लिए NCrunch विन्यास में जाओ और सच के कार्यक्षेत्र को कॉपी संदर्भित विधानसभाओं की स्थापना की।

NCrunch confuguration screenshot

+0

+1 यह समाधान मेरे लिए पूरी तरह से काम किया। सुनिश्चित नहीं है कि कोई बड़ा प्रदर्शन प्रभाव है या नहीं। –

2

मैं एक साल या के लिए harriyott के सुझाव का उपयोग किया गया। लेकिन फिर यह समस्या हमारे टीएफएस-बिल्डसर पर भी खुश है। तो अब मैं निनजेक्ट को स्वचालित रूप से सभी एक्सटेंशन लोड करने से बचता हूं और उन्हें मैन्युअल रूप से लोड करता हूं। यह #if, #endif से बचा जाता है और एक ही कोड Resharper और NCrunch पर चलेंगे:

var kernel = new StandardKernel(new NinjectSettings { LoadExtensions = false}); 
kernel.Load<FuncModule>(); 

बाकी अपरिवर्तित है:

kernel.Bind<IFooFactory>().ToFactory(() => new UseFirstParameterAsNameInstanceProvider()); 
kernel.Bind<IFoo>().To<BarFoo>().Named("Bar"); 

var factory = kernel.Get<IFooFactory>(); 
var bar = factory.CreateFoo("Bar"); 
Assert.Equal(typeof(BarFoo), bar.GetType());