• 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

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

    • Bulk Crap Uninstaller 6.2 by Razvan Serea Bulk Crap Uninstaller is a free (as in speech) program uninstaller. It excels at removing large amounts of applications with minimal user input. It can clean up leftovers, detect orphaned applications, run uninstallers according to premade lists, and much more. Even though BCU was made with IT pros in mind, by default it is so straight-forward that anyone can use it effortlessly! Bulk Crap Uninstaller features: Detect and uninstall Windows Store apps Uninstall multiple items at once to speed up the process (with collision prevention) Uninstall any number of applications in a single batch Minimal user input is required during uninstallation Can find and remove leftovers after uninstallation Can uninstall some apps even if they don't have any uninstallers Detects applications with damaged or missing uninstallers Adds quiet uninstall options to some uninstallers, even if they do not support them by default Uninstall lists for automation Startup manager Verification of uninstaller certificates Fully portable, settings are saved to a single file Bulk Crap Uninstaller 6.2 changelog: Features Add invalid-uninstaller view preset by @breshinotestachegira in #903 Add certificate and integrity columns to app list by @breshinotestachegira in #894 Improve Scoop custom path detection by @breshinotestachegira in #892 Fixes Improve uninstall list load error handling by @breshinotestachegira in #895 Fix tweak visibility filtering by @breshinotestachegira in #898 Fix orphaned-only view preset by @breshinotestachegira in #899 Stabilize icon handle ownership by @breshinotestachegira in #902 Fix: Use Directory.GetLastWriteTime for install date fallback by @AniketDeshmane in #908 Do not offer to send "no way to uninstall" error messages by @Klocman in #922 Ignore ERROR_BAD_CONFIGURATION when listing MSI components by @Klocman in #924 Eat InvalidOperationException coming from ListViewGroupAccessibleObject by @Klocman in #925 Harden BCU console export and size detection - Fix BCU-console export failures by @breshinotestachegira in #897 Harden registry factory parsing by @breshinotestachegira in #893 Guard startup uninstall list loading by @breshinotestachegira in #927 Clean generated files on uninstall by @One-Simon in #928 Translations Updated Hungarian translation by @titanicbobo in #875 Updated Vietnamese translations by @wanwanvxt in #918 Fix : Swedish translation causes UI overflow in some windows by @Leise-Shadow in #865 Other Fix publish script after v6.1 by @tsiakoulias in #868 Updated the localization pack Repository Moved the repository under a new BCUninstaller organization (old links still work) Added two maintainers: @hazeliscoding and @One-Simon Added PR merge rules (require up-to-date approval and CI to pass) Updated CI script to also build the launcher (only for testing, not included in artifacts) Download: Bulk Crap Uninstaller 6.2 | 8.8 MB (Open Source) Download: Bulk Crap Uninstaller Portable | 11.6 MB View: Bulk Crap Uninstaller Home Page | GitHub | Screenshot Get alerted to all of our Software updates on Twitter at @NeowinSoftware
    • If built properly, swapping out the backend should be an easy task, but as the article points out, it's just Apple not wanting to do this.
    • Microsoft's new Xbox Shutdown change promises massive power efficiency gains by Pulasthi Ariyasinghe Microsoft has been delivering a lot of changes for Xbox Insiders to test in recent weeks, and today, another wave of changes aimed at consoles was announced. The latest drop is testing features that let users find mutual friends easier, customize their UI, and streamline wishlisting. When looking at an Xbox friend's profile, an option will appear to see mutual friends, perhaps to get a refresher on how you know that person. This will depend on the privacy settings. The same applies to when checking the profile of a person who is not in the friends list, offering a quick way to find out if this is a known connection. Next, Microsoft is giving the option to change how the 'Home' and 'Games & Apps' sections show off available games. There is a new poster style that users can enable for an "immersive library experience." "We’ve also made personalization settings easier to navigate and customize by separating Home and My Games & apps into separate sections," adds the company. "And to make personalization even more accessible, we’ve added new shortcuts throughout menus, so you can quickly jump in and tailor your XBOX experience the way you want." Moreover, heading to the store page of an unreleased game will now offer players the option to wishlist directly from the game card. Lastly, Microsoft is making a change to Xbox One and Xbox Series X|S consoles that are in Sleep mode, making them use the more energy-saving 'Shutdown' mode instead automatically. The company says this can increase power savings by up to 20 times without impacting "performance, gameplay, or your ability to receive system, games or apps updates overnight." The only down side seems to be a longer startup time that can take up to 45 seconds. The setting was originally introduced in 2023, and this is only the latest update to it. The power option can be changed from the console settings at any time. This Xbox Insider update is rolling out today to select members of the program. As usual, Microsoft aims to bring it to more Insiders over time before they reach all Xbox owners. Head here to find out how to join the Xbox Insider Program to get a chance to test these features and upcoming ones on both consoles and PC.
    • 2 was a fun game but felt a bit shallow, like not enough there. I hope this expansion fixes that.
  • Recent Achievements

    • Rookie
      lamborghiniv10 went up a rank
      Rookie
    • One Month Later
      pinnclepd earned a badge
      One Month Later
    • First Post
      X-No-file earned a badge
      First Post
    • One Month Later
      johnjacobb40 earned a badge
      One Month Later
    • One Year In
      Primer1st earned a badge
      One Year In
  • Popular Contributors

    1. 1
      +primortal
      507
    2. 2
      PsYcHoKiLLa
      211
    3. 3
      +Edouard
      145
    4. 4
      Steven P.
      88
    5. 5
      ATLien_0
      80
  • Tell a friend

    Love Neowin? Tell a friend!