আমি রানটাইমের সময় একটি নেট নেট ডিসেম্বল লোড করতে পারি এবং কেবল নাম জেনে কোনও টাইপ ইনস্ট্যান্ট করতে পারি?


178

প্রকল্পটিতে অ্যাসেমব্লির কোনও রেফারেন্স যোগ না করে যদি আমার কেবল ডিএলএল নাম এবং ক্লাসের নাম থাকে তবে রানটাইমে কোনও বস্তু ইনস্ট্যান্ট করা সম্ভব? ক্লাসটি একটি ইন্টারফেস প্রয়োগ করে, তাই আমি একবার ক্লাসটি ইনস্ট্যান্ট করলে আমি তারপরে এটি ইন্টারফেসে কাস্ট করব।

সমাবেশ নাম:

library.dll

নাম টাইপ করুন:

Company.Project.Classname


সম্পাদনা: আমার ডিএলএল এর নিখুঁত পথ নেই, তাই Assembly.LoadFileকাজ করবে না। ডিএলএল অ্যাপ্লিকেশন রুটে, সিস্টেম 32, এমনকি জিএসি-তে লোড হতে পারে।

উত্তর:


221

হ্যাঁ. Assembly.LoadFromঅ্যাসেমব্লিকে মেমোরিতে লোড করতে আপনাকে ব্যবহার করতে হবে, তারপরে আপনি Activator.CreateInstanceআপনার পছন্দসই ধরণের উদাহরণ তৈরি করতে ব্যবহার করতে পারেন । প্রতিবিম্বটি ব্যবহার করে আপনাকে প্রথমে প্রকারটি দেখতে হবে। এখানে একটি সহজ উদাহরণ:

Assembly assembly = Assembly.LoadFrom("MyNice.dll");

Type type = assembly.GetType("MyType");

object instanceOfMyType = Activator.CreateInstance(type);

হালনাগাদ

আপনার যখন অ্যাসেম্বলি ফাইলের নাম এবং প্রকারের নাম থাকে, আপনি Activator.CreateInstance(assemblyName, typeName)এটি কোনও প্রকারে সমাধানের জন্য .NET টাইপ রেজোলিউশনটি জিজ্ঞাসা করতে পারেন । আপনি চেষ্টা / ক্যাপচারের সাহায্যে এটি মোড়ানো করতে পারেন যাতে এটি ব্যর্থ হলে আপনি এমন ডিরেক্টরিগুলির অনুসন্ধান করতে পারেন যেখানে আপনি বিশেষত অতিরিক্ত অ্যাসেম্বলিগুলি সঞ্চয় করতে পারেন যা অন্যথায় অনুসন্ধান করা যায় না। এটি সেই সময়ে পূর্বের পদ্ধতিটি ব্যবহার করবে।


2
আমার কাছে dll এর পরম পাথ নেই, তাই এসএমএলবি। লডফিল ect। কাজ করবে না, অন্য কোন ধারণা?
মেগা বাইট

@rp সাহায্য করতে সর্বদা খুশি (এবং কেবল এটি বলার জন্য এক বছর দেরীতে!)
জেফ ইয়টস

2
@ মেগাবাইট: লোডফ্র্যাম লোডফাইলে পৃথক। এটি আপনার নির্ভরতাগুলি সমাধান করবে এবং এটি পরিচিত পথগুলি (জিএসি, এক্সি এক্স ডিরেক্টরি) ইত্যাদি থেকে ডিএলএল নামটি সমাধান করবে more আরও তথ্যের জন্য এমএসডিএন দেখুন।
জেফ ইয়েটস

1
আরও একটি জিনিস ... (আমাকে আবার) উম, টাইপ নাম হিসাবে আপনার কেবল "মাই টাইপ" থাকতে পারে না, এটি অবশ্যই NAMESPACE অনুসরণ করা উচিত। সুতরাং এটি আরও সঠিক হবে:Type type = assembly.GetType("MyNamespace"+"."+"MyType");
সিপি

1
@ সিপি: প্রযুক্তিগতভাবে, একটি প্রকারের এটি পুরো নাম-গতির নাম (নেমস্পেসের ধারণাটি একটি ভাষা সুবিধার)। সিএলআর-তে কোনও নামস্থান ছাড়াই আপনার টাইপ থাকতে পারে - আমি কেবল একটি অতিরিক্ত সরল উদাহরণ দিয়েছি।
জেফ ইয়েটস

36

বিভিন্ন Load*পদ্ধতির সীমাবদ্ধতা বিবেচনা করুন । থেকে দুটিই MSDN ডক্স ...

লোডফিল লোডফ্রম প্রসঙ্গে ফাইল লোড করে না এবং লোডফ্রম পদ্ধতি যেমন লোড পাথ ব্যবহার করে নির্ভরতাগুলি সমাধান করে না

লোড প্রসঙ্গে আরও তথ্য ডক্সে পাওয়া যাবে LoadFrom


19

অ্যাক্টিভেটর.ক্রিয়েট ইনস্ট্যান্সের কাজ করা উচিত।

IFace object = (IFace)Activator.CreateInstance( "AssemblyName",
                                                "TypeName" )
                               .Unwrap();

বিঃদ্রঃ: প্রকারের নামটি অবশ্যই পুরোপুরি যোগ্যতাযুক্ত টাইপ হতে হবে।

উদাহরণ:

var aray = (IList)Activator.CreateInstance("mscorlib","System.Collections.ArrayList").Unwrap();
aray.Add(10);

foreach (object obj in aray)
{
    Console.WriteLine(obj);
}

1
এই সম্পর্কে একটি নোট: TypeNameসম্পূর্ণরূপে যোগ্য হতে হবে। আমি এই মত কল করতে হয়েছিল: Activator.CreateInstance("MyAssembly","MyAssembly.TypeName") এবং এটি একটি ফিরে ObjectHandle। আপনার ইন্টারফেসে নামার জন্য আপনাকে যা করতে হবেObjectHandle.UnWrap()
অ্যান্টনি সটাইল

7

আমি এই প্রশ্ন এবং কিছু উত্তর খুব দরকারী খুঁজে পেয়েছি, তবে আমার পাথ সমস্যা ছিল, সুতরাং এই উত্তরটি বিন ডিরেক্টরি পথ খুঁজে বের করে লাইব্রেরিটি লোড করে।

প্রথম সমাধান:

string assemblyName = "library.dll";
string assemblyPath = HttpContext.Current.Server.MapPath("~/bin/" + assemblyName);
Assembly assembly = Assembly.LoadFrom(assemblyPath);
Type T = assembly.GetType("Company.Project.Classname");
Company.Project.Classname instance = (Company.Project.Classname) Activator.CreateInstance(T);

দ্বিতীয় সমাধান

string assemblyName = "library.dll";
string assemblyPath = HttpContext.Current.Server.MapPath("~/bin/" + assemblyName);
Assembly assembly = Assembly.LoadFile(assemblyPath);
(Company.Project.Classname) instance = (Company.Project.Classname) assembly.CreateInstance("Company.Project.Classname");

আপনি ইন্টারফেসের জন্য একই নীতিটি ব্যবহার করতে পারেন (আপনি একটি শ্রেণি তৈরি করছেন তবে ইন্টারফেসে কাস্টিং করছেন), যেমন:

(Company.Project.Interfacename) instance = (Company.Project.Interfacename) assembly.CreateInstance("Company.Project.Classname");

এই উদাহরণটি ওয়েব অ্যাপ্লিকেশনের জন্য তবে ডেস্কটপ অ্যাপ্লিকেশনের জন্যও একই রকম ব্যবহার করা যেতে পারে, উদাহরণস্বরূপ, কেবলমাত্র পথটি বিভিন্ন উপায়ে সমাধান করা হয়

Path.GetDirectoryName(Application.ExecutablePath)

5

এটি সহজ.

এমএসডিএন থেকে উদাহরণ:

public static void Main()
{
    // Use the file name to load the assembly into the current
    // application domain.
    Assembly a = Assembly.Load("example");
    // Get the type to use.
    Type myType = a.GetType("Example");
    // Get the method to call.
    MethodInfo myMethod = myType.GetMethod("MethodA");
    // Create an instance.
    object obj = Activator.CreateInstance(myType);
    // Execute the method.
    myMethod.Invoke(obj, null);
}

এখানে একটি রেফারেন্স লিঙ্ক

https://msdn.microsoft.com/en-us/library/25y1ya39.aspx


কোডটির গতিশীল লোডিং সমর্থন করার জন্য এটি একটি ভয়ঙ্কর উপায়। এমএস সবসময় আমাদের অনেক বেশি বিবরণ পেতে বাধ্য করতে পছন্দ করে।
ক্লিয়ারার

3

ফ্রেমওয়ার্ক থেকে শুরু v4.5 আপনি ব্যবহার করতে পারেন Activator.CreateInstanceFrom () সমাহারগুলি মধ্যে সহজেই instantiate ক্লাস। নিম্নলিখিত উদাহরণটি দেখায় যে এটি কীভাবে ব্যবহার করতে হয় এবং কীভাবে কোনও প্যারামিটারগুলি পাস করে একটি পদ্ধতি কল করা যায় এবং ফেরতের মান পাওয়া যায়।

    // Assuming moduleFileName contains full or valid relative path to assembly    
    var moduleInstance = Activator.CreateInstanceFrom(moduleFileName, "MyNamespace.MyClass");
    MethodInfo mi = moduleInstance.Unwrap().GetType().GetMethod("MyMethod");
    // Assuming the method returns a boolean and accepts a single string parameter
    bool rc = Convert.ToBoolean(mi.Invoke(moduleInstance.Unwrap(), new object[] { "MyParamValue" } ));

2

হ্যাঁ. এই মুহুর্তে আমি ব্যক্তিগতভাবে উপলব্ধ হয়েছি এমন কোনও উদাহরণ আমার কাছে নেই। কিছু খুঁজে পেলে পরে পোস্ট করব। মূলত আপনি অ্যাসেম্বলি লোড করতে এবং তার জন্য আপনার যা প্রয়োজন তা টানতে প্রতিবিম্বটি ব্যবহার করবেন।

ইতিমধ্যে, এই লিঙ্কটি আপনাকে শুরু করা উচিত:

রানটাইমে অযৌক্তিক সমাবেশগুলি লোড করার জন্য প্রতিবিম্ব ব্যবহার করা


2
((ISomeInterface)Activator.CreateInstance(Assembly.LoadFile("somePath").GetTypes()[0])).SomeInterfaceMethod();

2

আপনি * এসেম্বলি.লড করুন ** পদ্ধতিগুলি ব্যবহার করে কোনও সমাবেশ লোড করতে পারেন। অ্যাক্টিভেটর.ক্রিয়েট ইনস্ট্যান্স ব্যবহার করে আপনি যে ধরণের পছন্দ করতে চান তার নতুন উদাহরণ তৈরি করতে পারেন। মনে রাখবেন যে শ্রেণিটি আপনি লোড করতে চান তার পুরো টাইপের নামটি আপনাকে ব্যবহার করতে হবে (উদাহরণস্বরূপ নেমস্পেস.সুবনেমস্পেস.ক্লাসনাম )। পদ্ধতি ব্যবহার করে InvokeMember এর প্রকার শ্রেণী আপনি ধরনের উপর পদ্ধতি ডাকা পারবেন না।

এছাড়াও, অ্যাকাউন্টটি একবারে লোড হয়ে গেলে, পুরো অ্যাপডোমেনটি খুব বেশি লোড না করা পর্যন্ত কোনও অ্যাসেমব্লিকে আনলোড করা যায় না (এটি মূলত একটি মেমরি ফুটো)।


2

আপনার প্রকল্পের জন্য এই ধরণের কার্যকারিতা কতটা স্বতন্ত্র তা নির্ভর করে আপনি এমইএফ এর মতো কিছু বিবেচনা করতে চাইতে পারেন যা আপনার জন্য উপাদানগুলির একসাথে লোডিং এবং বেঁধে রাখার যত্ন নেবে।


2
Assembly assembly = Assembly.LoadFrom("MyAssembly.dll");

Type type = assembly.GetType("MyType");

dynamic instanceOfMyType = Activator.CreateInstance(type);

সুতরাং এই পদ্ধতিতে আপনি মেথডিনফো না পেয়ে ফাংশনগুলি ব্যবহার করতে পারেন এবং তারপরে এটি শুরু করে Youআপনি এই উদাহরণটি পছন্দ করবেনঅফমাইটাইপ.মথোদনেম (); তবে আপনি ইন্টেলিসেন্স ব্যবহার করতে পারবেন না কারণ গতিশীল প্রকারগুলি রানটাইম টাইপ করা হয়, সংকলনের সময় নয়।


1

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

এছাড়াও, আপনি আপনার প্রয়োজনীয়তার উপর নির্ভর করে বিধানসভা ক্লাসে "লোড" দিয়ে শুরু হওয়া অন্য স্থিতিশীল পদ্ধতির একটিতে কল করতে পারেন।


0

আপনি এই জিনিস এইভাবে করতে পারেন:

using System.Reflection;

Assembly MyDALL = Assembly.Load("DALL"); //DALL name of your assembly
Type MyLoadClass = MyDALL.GetType("DALL.LoadClass"); // name of your class
 object  obj = Activator.CreateInstance(MyLoadClass);
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.