এসেম্বলি.গেটটাইপস () কল করার সময় কীভাবে প্রতিবিম্বতা টাইপ লোড ধারণাটি রোধ করবেন


99

আমি এর অনুরূপ কোড ব্যবহার করে নির্দিষ্ট ইন্টারফেস প্রয়োগ করার ধরণের জন্য অ্যাসেম্বলি স্ক্যান করার চেষ্টা করছি:

public List<Type> FindTypesImplementing<T>(string assemblyPath)
{
    var matchingTypes = new List<Type>();
    var asm = Assembly.LoadFrom(assemblyPath);
    foreach (var t in asm.GetTypes())
    {
        if (typeof(T).IsAssignableFrom(t))
            matchingTypes.Add(t);
    }
    return matchingTypes;
}

আমার সমস্যাটি হ'ল, আমি কিছু ক্ষেত্রে ReflectionTypeLoadExceptionফোন করার সময় পাই asm.GetTypes()eg উদাহরণস্বরূপ, যদি অ্যাসেমব্লিতে এমন কোনও সমাবেশ থাকে যা বর্তমানে পাওয়া যায় না re

আমার ক্ষেত্রে, আমি সমস্যাগুলির কারণগুলিতে আগ্রহী নই। আমি যে ধরণের জন্য অনুসন্ধান করছি তা অ-উপলভ্য সমাবেশগুলির প্রয়োজন হয় না।

প্রশ্নটি হ'ল কীভাবে কোনও উপায় বাদ দেওয়া বা উপেক্ষা করা সম্ভব যেগুলি ব্যতিক্রম ঘটায় তবুও সমাবেশে থাকা অন্যান্য ধরণের প্রক্রিয়াগুলি এখনও প্রক্রিয়া করে?


4
আপনি যা খুঁজছেন তার চেয়ে অনেক বেশি নতুন লেখা হতে পারে তবে এমইএফ আপনাকে অনুরূপ কার্যকারিতা দেয়। কেবলমাত্র আপনার প্রতিটি ক্লাসকে একটি [এক্সপোর্ট] ট্যাগ দিয়ে চিহ্নিত করুন যা এটি প্রয়োগ করে ইন্টারফেসটি নির্দিষ্ট করে। তারপরে আপনি কেবল সেই আগ্রহী ইন্টারফেসগুলিই আমদানি করতে পারেন।
ডার্ক জঘন্যতম

@ ড্রু, আপনার মন্তব্যের জন্য ধন্যবাদ আমি এমইএফ ব্যবহারের কথা ভাবছিলাম, তবে চেয়েছিলাম আরও একটি সস্তার সমাধান আছে কিনা।
এম

প্লাগইন ক্লাস ফ্যাক্টরিটিকে একটি সুপরিচিত নাম দেওয়া যাতে আপনি কেবল অ্যাক্টিভেটর ব্যবহার করতে পারেন re তবুও, যদি আপনি কোনও সমাবেশ সমাধান সমস্যার কারণে এখনই এই ব্যতিক্রমটি পান তবে আপনি সম্ভবত পরে তা পেয়ে যাবেন।
হ্যানস প্যাস্যান্ট

4
@ હંস: আমি নিশ্চিত না যে আমি পুরোপুরি বুঝতে পেরেছি। আমি যে সমাবেশটি স্ক্যান করছি সেটিতে প্রদত্ত ইন্টারফেস প্রয়োগকারী যে কোনও ধরণের সংখ্যক উপাদান থাকতে পারে, সুতরাং একটি সুপরিচিত প্রকার নেই। (এবং এছাড়াও: আমি একাধিক সমাবেশকে স্ক্যান করছি, কেবল একটিই নয়)
এম

4
আমার প্রায় একই কোড এবং একই সমস্যা রয়েছে। এবং আমি যে সমাবেশটি ঘুরে দেখি তা প্রদত্ত AppDomain.CurrentDomain.GetAssemblies(), এটি আমার মেশিনে কাজ করে তবে অন্যান্য মেশিনে নয়। আমার কার্যনির্বাহী থেকে হ্যাক কেন কিছু সভা সমাবেশে পাঠযোগ্য / লোডযোগ্য হবে না ??
v.oddou

উত্তর:


130

একটি মোটামুটি বাজে উপায় হবে:

Type[] types;
try
{
    types = asm.GetTypes();
}
catch (ReflectionTypeLoadException e)
{
    types = e.Types;
}
foreach (var t in types.Where(t => t != null))
{
    ...
}

যদিও এটি করতে অবশ্যই বিরক্তিকর। "ক্লায়েন্ট" কোডটিতে এটিকে আরও ভাল করতে আপনি কোনও এক্সটেনশন পদ্ধতি ব্যবহার করতে পারেন:

public static IEnumerable<Type> GetLoadableTypes(this Assembly assembly)
{
    // TODO: Argument validation
    try
    {
        return assembly.GetTypes();
    }
    catch (ReflectionTypeLoadException e)
    {
        return e.Types.Where(t => t != null);
    }
}

তুমি ভালো সরাতে পারেন returnধরা ব্লক থেকে বের বিবৃতি - আমি ভয়ঙ্কর করছি সেখানে নিজেকে হচ্ছে প্রখর, কিন্তু এটা সম্ভবত হয় সবচেয়ে কম কোড ...


4
ধন্যবাদ, এটি একটি সমাধান বলে মনে হচ্ছে (এবং আমি একমত, এটি একটি পরিষ্কার সমাধান বলে মনে হয় না)।
এম

4
আপনি ব্যতিক্রমের মধ্যে প্রকাশিত ধরণের তালিকা ব্যবহার করার চেষ্টা করার পরে এই সমাধানটিতে এখনও সমস্যা রয়েছে। প্রকারের লোড ব্যতিক্রমের কারণ যাই হউক না কেন, ফাইলনটফাউন্ড, ব্যাডিম্যাজ ইত্যাদি issue
মিষ্টিফা

@ সুইটফা: হ্যাঁ, এটি খুব সীমাবদ্ধ - তবে যদি ওপিতে কেবল নামগুলি সন্ধান করতে হয় তবে উদাহরণস্বরূপ, এটি ঠিক হওয়া উচিত।
জন স্কিটি

4
মজার কথা, এই পোস্টটি এখানে উল্লেখ করা হয়েছে, বেশ আকর্ষণীয়: haacked.com/archive/2012/07/23/…
anhoppe

@ সুইটফা ফিরে আসা ধরণের ক্ষেত্রে ফাইলনটফাউন্ড ব্যতিক্রমের সমস্যা এড়াতে আমি যা করি তা : From t As Type In e.Types Where (t IsNot Nothing) AndAlso (t.TypeInitializer IsNot Nothing)এটি দুর্দান্ত কাজ করছে বলে মনে হচ্ছে।
এলেক্ট্রো স্টুডিওগুলি

22

যদিও এটি প্রদর্শিত হয় যে কোনও সময়ে প্রতিচ্ছবি টাইপলয়েডএক্সসেপশন প্রাপ্ত না করে কিছুই করা যায় না, উপরের উত্তরগুলি সীমাবদ্ধ যে ব্যতিক্রম থেকে সরবরাহ করা প্রকারগুলি ব্যবহারের যে কোনও প্রয়াস এখনও মূল সমস্যার সাথে সমস্যাটি দেবে যা টাইপটি লোড করতে ব্যর্থ হয়েছিল।

এটি কাটিয়ে উঠতে নিম্নলিখিত কোডটি সমাবেশের মধ্যে অবস্থিতগুলির মধ্যে প্রকারের সীমাবদ্ধ করে এবং একটি প্রিকিকেটকে আরও প্রকারের তালিকাকে সীমাবদ্ধ করার অনুমতি দেয়।

    /// <summary>
    /// Get the types within the assembly that match the predicate.
    /// <para>for example, to get all types within a namespace</para>
    /// <para>    typeof(SomeClassInAssemblyYouWant).Assembly.GetMatchingTypesInAssembly(item => "MyNamespace".Equals(item.Namespace))</para>
    /// </summary>
    /// <param name="assembly">The assembly to search</param>
    /// <param name="predicate">The predicate query to match against</param>
    /// <returns>The collection of types within the assembly that match the predicate</returns>
    public static ICollection<Type> GetMatchingTypesInAssembly(this Assembly assembly, Predicate<Type> predicate)
    {
        ICollection<Type> types = new List<Type>();
        try
        {
            types = assembly.GetTypes().Where(i => i != null && predicate(i) && i.Assembly == assembly).ToList();
        }
        catch (ReflectionTypeLoadException ex)
        {
            foreach (Type theType in ex.Types)
            {
                try
                {
                    if (theType != null && predicate(theType) && theType.Assembly == assembly)
                        types.Add(theType);
                }
                // This exception list is not exhaustive, modify to suit any reasons
                // you find for failure to parse a single assembly
                catch (BadImageFormatException)
                {
                    // Type not in this assembly - reference to elsewhere ignored
                }
            }
        }
        return types;
    }

4

আপনি কি অ্যাসেম্বলি বিবেচনা করেছেন ? আপনি যা করার চেষ্টা করছেন তা বিবেচনা করে, এটি যথেষ্ট হতে পারে।


4
হ্যাঁ আমি এটা বিবেচনা করেছিলাম। তবে আমি এটি ব্যবহার করিনি কারণ অন্যথায় আমাকে কোনও নির্ভরতা নিজেই লোড করতে হবে। এছাড়াও কোডটি রিফ্লেকশনঅললাইডের সাথে কার্যকর করা যাবে না (আপনি যে পৃষ্ঠাটিতে লিঙ্ক করেছেন সেটিতে মন্তব্যগুলি বিভাগ দেখুন)।
এম

3

আমার ক্ষেত্রে, অ্যাপ্লিকেশন ফোল্ডারে অবাঞ্ছিত সমাবেশগুলির উপস্থিতি দ্বারা একই সমস্যা হয়েছিল। বিন ফোল্ডারটি সাফ করার চেষ্টা করুন এবং অ্যাপ্লিকেশনটি পুনর্নির্মাণ করুন।

আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.