का उपयोग होता है मेरे पास एक आसान उपयोगिता विधि है जो कोड लेती है और इन-मेमोरी असेंबली को थूकती है। (यह CSharpCodeProvider
का उपयोग करता है, हालांकि मुझे नहीं लगता कि कि कोई फर्क करना चाहिए।) यह विधानसभा प्रतिबिंब के साथ किसी भी अन्य की तरह काम करता है, लेकिन जब dynamic
कीवर्ड के साथ किया है, यह एक RuntimeBinderException
के साथ विफल रहा है:गतिशील रूप से निर्मित असेंबली पर एक गतिशील विधि को बांधने का प्रयास करने से RuntimeBinderException
'वस्तु' 'साउंड' के लिए एक परिभाषा शामिल नहीं है
उदाहरण:
var assembly = createAssembly("class Dog { public string Sound() { return \"woof\"; } }");
var type = assembly.GetType("Dog");
Object dog = Activator.CreateInstance(type);
var method = type.GetMethod("Sound");
var test1Result = method.Invoke(dog, null); //This returns "woof", as you'd expect
dynamic dog2 = dog;
String test2Result = dog2.Sound(); //This throws a RuntimeBinderException
किसी को भी कारण है कि डीएलआर इस संभाल करने में सक्षम नहीं है पता है? क्या इस परिदृश्य को ठीक करने के लिए कुछ भी किया जा सकता है?
संपादित करें:
createAssembly विधि:
अस्वीकरण: इस सामान में से कुछ विस्तार तरीकों, कस्टम प्रकार, आदि यह स्वतः स्पष्ट होना चाहिए, हालांकि होता है।
private Assembly createAssembly(String source, IEnumerable<String> assembliesToReference = null)
{
//Create compiler
var codeProvider = new CSharpCodeProvider();
//Set compiler parameters
var compilerParameters = new CompilerParameters
{
GenerateInMemory = true,
GenerateExecutable = false,
CompilerOptions = "/optimize",
};
//Get the name of the current assembly and everything it references
if (assembliesToReference == null)
{
var executingAssembly = Assembly.GetExecutingAssembly();
assembliesToReference = executingAssembly
.AsEnumerable()
.Concat(
executingAssembly
.GetReferencedAssemblies()
.Select(a => Assembly.Load(a))
)
.Select(a => a.Location);
}//End if
compilerParameters.ReferencedAssemblies.AddRange(assembliesToReference.ToArray());
//Compile code
var compilerResults = codeProvider.CompileAssemblyFromSource(compilerParameters, source);
//Throw errors
if (compilerResults.Errors.Count != 0)
{
throw new CompilationException(compilerResults.Errors);
}
return compilerResults.CompiledAssembly;
}
मेरे हिस्से पर मूर्खतापूर्ण गलती। 'गतिशील' अभिगम्यता का सम्मान करता है, इसलिए यह किसी अन्य असेंबली से गैर-सार्वजनिक कोड निष्पादित नहीं कर सकता है, जबकि प्रतिबिंब अभिगम्यता के बारे में थोड़ा सा परवाह नहीं करता है। धन्यवाद। – MgSam