मैं यूनिटी कंटेनर में रजिस्टर टाइप विधि का आह्वान करने की कोशिश कर रहा हूं। रजिस्टर टाइप में कुल 16 ओवरराइड हैं (उनमें से कुछ पैरामीटर कुछ प्रकार हैं)।जेनिक्स और ओवरराइड के साथ प्रतिबिंब के माध्यम से एक विधि का आह्वान
मैं के बराबर प्रदर्शन करने के लिए कोशिश कर रहा हूँ: GetMethod का उपयोग
Container.RegisterType<IMyDataProvider, MockData.MockProvider>("MockData", new ContainerControlledLifetimeManager())
() पूरी तरह विफल हो गया था, इसलिए मैं इस बदसूरत बात कर समाप्त हो गया:
MethodInfo registerTypeGeneric = Container.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance).
Where(p => p.ToString() == "Microsoft.Practices.Unity.IUnityContainer RegisterType[TFrom,TTo](System.String, Microsoft.Practices.Unity.LifetimeManager, Microsoft.Practices.Unity.InjectionMember[])").FirstOrDefault();
MethodInfo registerTypeSpecific = registerTypeGeneric.MakeGenericMethod(new Type[] { typeof(IMyDataProvider), Assembly.LoadFrom("MockData.dll").GetType("MockData.MockProvider") });
registerTypeSpecific.Invoke(Container, new object[] { "MockData", new ContainerControlledLifetimeManager() });
और यह खूबसूरती से काम करता है , जब तक कि शिकायत न हो, तब तक शिकायत करें क्योंकि मेरे पास इंजेक्शनमेन पैरामीटर नहीं हैं (वे वैकल्पिक हैं और मेरे पास देने के लिए कोई नहीं है)। इसलिए, दस्तावेज़ीकरण के अनुसार, मुझे वैकल्पिक पैरामीटर के साथ एक विधि कॉल करने के लिए Type.InvokeMember() का उपयोग करना होगा।
Binder binder = new BootstrapperBinder();
Container.GetType().InvokeMember("RegisterType",
BindingFlags.Instance | BindingFlags.Public | BindingFlags.OptionalParamBinding | BindingFlags.InvokeMethod,
binder,
Container,
new object[] { "MockData", new ContainerControlledLifetimeManager() });
मेरे BoostrapperBinder वर्ग करता है:
तो मैं ऐसा किया
public override MethodBase BindToMethod(BindingFlags bindingAttr, MethodBase[] match, ref object[] args, ParameterModifier[] modifiers, System.Globalization.CultureInfo culture, string[] names, out object state)
{
Type mockProvider = Assembly.LoadFrom("MockData.dll").GetType("MockData.MockProvider");
state = new object();
MethodInfo mi = Container.GetType().GetMethods(BindingFlags.Public | BindingFlags.Instance).
Where(p => p.ToString() == "Microsoft.Practices.Unity.IUnityContainer RegisterType[TFrom,TTo](System.String, Microsoft.Practices.Unity.LifetimeManager, Microsoft.Practices.Unity.InjectionMember[])").FirstOrDefault();
return mi.MakeGenericMethod(new Type[] { typeof(ICarrierApprovalDataChangeAccessorEndPoint), mockProvider });
}
हाँ, यह बदसूरत है, लेकिन मैं तो बस, इस oen मामले के लिए इसका इस्तेमाल करते हैं तो यह काम करता है।
अब, समस्या यह है कि यह अभी भी तीसरे पैरामीटर की कमी के बारे में शिकायत कर रहा है। मैं शून्य या गुम नहीं कर सकता। या तो वाल्व, या यह croaks। मैंने बाध्यकारीफ्लैग के साथ और बिना कोशिश की है। ऑप्शनल पैराम बाइंडिंग। मैं उलझन में हूं।
GetMethods में LINQ एक से अधिक रिटर्न के कारण विफल रहता है (इसमें 16 ओवरराइड हैं, उनमें से कुछ अलग जेनेरिक प्रकार पैरामीटर के साथ हैं), लेकिन अगर मैं methodinfo प्राप्त करने के लिए अपना रास्ता उपयोग करता हूं, तो Invoke अभी भी शून्य के साथ विफल रहता है RegisterType() विधि में संदर्भ अपवाद। चूंकि कंटेनर शून्य नहीं है, इसलिए मैं केवल अनुमान लगा सकता हूं कि शून्य पैरामीटर कारण है। – Pete
यह ठीक करना आसान है। 'सिंगलऑर्डफॉल्ट' पर कॉल करने से पहले '। जहां (m => m.GetGenericArguments()। गणना() == 2)' जोड़ें। – jason
समस्या के लिए आप 'शून्य' के साथ अनुभव कर रहे हैं, एक स्थिर विधि आमंत्रण के माध्यम से विधि का आह्वान करने का प्रयास करें (यानी, प्रतिबिंब को हटा दें)। बस 'कंटेनर। रजिस्ट्रार टाइप करें ("MockData", नया कंटेनर नियंत्रित नहीं लाइफटाइम मैनेजर(), शून्य)' और देखें कि आपको एक ही समस्या है या नहीं। यदि आप करते हैं, तो समस्या गतिशील आमंत्रण नहीं है और इसके बजाय यह कुछ और है (शायद जिस तरह से आप कंटेनर सेट करते हैं?)। –
jason