• 0

C# Better & more efficient way to load DLL dynamically & get interf


Question

Hi,

Been using the code below to load a dll dynamically and get an instance of certain interface. This was done way back in .NET 2 days. What is a better & more efficient way to do this using .NET 4 functionality?


// Usage
ICountryHandler pCountryHandler = GetInstanceFromModule<ICountryHandler>("Company.Product.Country.Australia.dll");

public static TInterface GetInstanceFromModule<TInterface>(string AModuleName)
where TInterface : class
{
Assembly pAssembly;
ConstructorInfo pConstructor;
TInterface pInstance;
Type pInterface;
pAssembly = null;
if (AModuleName.Contains(Path.DirectorySeparatorChar.ToString()) || AModuleName.Contains(Path.AltDirectorySeparatorChar.ToString()) || AModuleName.Contains(Path.PathSeparator.ToString()) || AModuleName.Contains(Path.VolumeSeparatorChar.ToString()))
{
pAssembly = Assembly.LoadFrom(AModuleName);
}
else
{
pAssembly = Assembly.LoadFrom(Path.Combine(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location), AModuleName));
}
if (pAssembly != null)
{
foreach (Type pType in pAssembly.GetExportedTypes())
{
pInterface = pType.GetInterface(typeof(TInterface).ToString());
if (pInterface != null)
{
pConstructor = pType.GetConstructor(new Type[] { });
pInstance = pConstructor.Invoke(null) as TInterface;
if (pInstance != null)
{
return pInstance;
}
}
}
}
return null;
}
[/CODE]

TA :)

10 answers to this question

Recommended Posts

  • 0


pInterface = pType.GetInterface(typeof(TInterface).ToString());
if (pInterface != null)[/CODE]

I take it this tests if pType implements TInterface? I'd do:

[CODE]if (typeof(TInterface).IsAssignableFrom(pType))[/CODE]

Also rather than getting the default constructor and invoking explicitely, you could use Activator for that:

[CODE]
pConstructor = pType.GetConstructor(new Type[] { });
pInstance = pConstructor.Invoke(null) as TInterface;

// instead do
pInstance = (TInterface)Activator.CreateInstance(pType);[/CODE]

No need to use [font=courier new,courier,monospace]as[/font] and check for null since you just checked that pType implements TInterface: the cast must necessarily succeed.

None of this is .NET 4-specific but might allow you to cut down the number of lines a bit.

  • 0

You should divide that method into smaller methods - one to get the assembly from a string, one to get all types implementing an interface, and one to create an instance of all these types.

Your check for absolute path can be replaced with Path.IsPathRooted().

Also, stop using Hungarian notation...especially if you're not actually using the prefix but just using "p" at the beginning of everything. It's both ugly and useless. ( see http://msdn.microsoft.com/en-us/library/vstudio/ms229045.aspx - "Do not use Hungarian notation").

  • 0

Actually the biggest efficiency gains here would be by caching the results. Iterating all the types in an assembly can take a long time and you're doing it every time the method is called. Of course, measure your gains - how much time this method currently takes and how much you're saving (or wasting!) by doing things differently. You might find out this method takes an insignificant amount of time and you're just worrying for nothing.

  • Like 1
  • 0
  On 04/10/2012 at 07:58, Dr_Asik said:

Iterating all the types in an assembly can take a long time and you're doing it every time the method is called.

(Y)

Unless it's a once-off thing - then it's probably not worth overcomplicating it.

And just for fun, here's a LINQ version:

(PS: If you often need to test code snippets (not necessarily LINQ-related), LINQPad is invaluable)


public static TInterface GetInstanceFromModule<TInterface>() where TInterface : class
{
// Change this to load assembly from file
var pAssembly = Assembly.GetAssembly(typeof(TInterface));

// Magic!
if (pAssembly != null)
return pAssembly.GetExportedTypes()
.Where(t => t.IsClass)
.Where(t => typeof(TInterface).IsAssignableFrom(t))
.Select(t => (TInterface)Activator.CreateInstance(t))
.FirstOrDefault();

return null;
}
[/CODE]

Edit: It doesn't really increase efficiency, but does make it a lot easier on the eyes. And [i]slightly[/i] harder to debug :p

Edited by GreenMartian
  • 0

Thanks guys.

I am using hungarian notations as that is the coding practices where I work and I gotta follow their guidelines. I am going to implement few of these suggestions and see how things go. I am only calling this once for each DLL that I want to load and once they are loaded that is it.

I read somewhere to use newly introduced dynamic key word and use managed extensibility framework but I am stuck there... Any advice on that would be useful too.

Cheers :)

  • 0

Ah, didn't realise MEF is now built into .NET 4.

From your example, it looks like you're looking more into Dependency Injection (DI). From what I remember, MEF does it to some extent, but is more geared towards supporting extensions (I haven't actually used it, but did some reading on it a couple years ago, so feel free to correct me).

There are multiple frameworks that provide DI Containers. Personally, I've only used Castle Windsor. There's also Unity, and a few others.

Setup properly, DI containers make it ridiculously easy to inject interface implementations to other classes.

In a nutshell, you basically tell it once, at the start of your app, to load a config from an xml file like so:

container.Install(Configuration.FromXmlFile("settings.xml")

With the xml file looking something like

&lt;configuration&gt;
&lt;components&gt;
  &lt;component service="Namespace.ICountryHandler, AssemblyNameOfInterface"
	type="Namespace.AustralianHandler, AssemblyNameOfImplementor" /&gt;
&lt;/components&gt;
&lt;/configuration&gt;

And everywhere else in the code when you have a property of type ICountryHandler, you'll get the Australian handler.

PS: Thanks for mentioning MEF. I might revisit it and see what MS have been up to. There goes my weekend!

This topic is now closed to further replies.
  • Posts

    • You invoke the game bar and then can pin it with transparent background.
    • 100% agree with this " As for real framerate vs framegen framerate, I don't think they exactly want you to know, given that their marketing has been strongly focused on hiding the real framerate and pretending the generated one is all that matters..."
    • I also use the classic Start menu in Open Shell in Windows 10/11
    • However, you would have to invoke it with the Windows key + G; in other words, it's useless. It is Microsoft's logic of placing things, and that is a company who have no idea how to design anything.
    • Samsung 2TB 9100 PRO, 990 PRO NVMe SSDs have never been cheaper by Sayan Sen It looks like the NVMe SSD market is once again coming to life if you are out there hunting for deals. Samsung, for example, is offering its 9100 PRO and 990 PRO drives at great prices that you should absolutely look at if you want to save some major bucks. The discounts apply on 2TB models (purchase links down below). First up, we have the 9100 PRO. It is based on PCIe Gen5 and thus promises double the speed of the 990 PRO. Samsung claims to deliver sequential read and write speeds of up to 14,700 MB/s and 13,400 MB/s, respectively, on the 2TB model. In terms of random throughput, the claimed numbers for the 2TB SKU is 1850K IOPS for the reads and 2600K IOPS for writes. The on-board DRAM cache helps in this regard with 2GB of LPDDR4X on the 2TB. The SSD is built on Samsung's in-house 8th Gen TLC V-NAND flash memory and has endurance ratings of 1200 TBW (terabytes written). Gen5 SSDs are known to run quite hot and thus the included SSDs are a must. You may even upgrade to something even better if you are having trouble managing the heat. Speaking of heat, Samsung says that the drives have an operating temperature of 0 to 70 Celsius, and upon exceeding this temperature, the drive's controller will begin throttling quite heavily. Get it at the link below: SAMSUNG SSD 9100 PRO without Heatsink 2TB, PCIe 5.0x4 M.2 2280 (MZ-VAP2T0CW): $239.99 (Amazon US) || $239.99 (Shipped and Sold by Newegg US) 990 PRO is, on the other hand, the fastest Gen4 drive from Samsung. There are some obvious differences like lower speeds on this compared to the 9100 PRO. Sequential reads and writes are rated at 7450 MB/s and 6900 MB/s respectively. The random throughputs for reads and writes are 1400K IOPS and 1550K IOPS respectively. The 990 PRO is based on Samsung's 7th Gen V-NAND flash and it too is TLC. The endurance rating for this is the same as that of the 9100 PRO. Get it at the link below: Samsung 990 PRO SSD NVMe M.2 PCIe Gen4, M.2 2280, MZ-V9P2T0B/AM: $149.99 (Shipped and Sold Amazon US) || $149.99 (Shipped and Sold by Newegg US) This Amazon deal is US-specific and not available in other regions unless specified. If you don't like it or want to look at more options, check out the Amazon US deals page here. Get Prime (SNAP), Prime Video, Audible Plus or Kindle / Music Unlimited. Free for 30 days. As an Amazon Associate, we earn from qualifying purchases.
  • Recent Achievements

    • Week One Done
      OHI Accounting earned a badge
      Week One Done
    • One Month Later
      OHI Accounting earned a badge
      One Month Later
    • First Post
      Thornskade earned a badge
      First Post
    • Week One Done
      Higante88 earned a badge
      Week One Done
    • Conversation Starter
      CarloDuplessis earned a badge
      Conversation Starter
  • Popular Contributors

    1. 1
      +primortal
      719
    2. 2
      ATLien_0
      278
    3. 3
      Michael Scrip
      204
    4. 4
      +FloatingFatMan
      190
    5. 5
      Steven P.
      129
  • Tell a friend

    Love Neowin? Tell a friend!