2
\$\begingroup\$

Here is my code to retrieve a class from a different solution (both solutions are in the same folder) using an XML file:

var xml = XElement.Load("settings.xml");
var query = xml.Elements();
     foreach (var XMLProtocol in query)
     {
         string NameSpace = XMLProtocol.Element("NameSpace").Value;
         string ClassName = XMLProtocol.Element("ClassName").Value;
         string FrequencyType = XMLProtocol.Element("FrequencyType").Value;
         string FrequencyValue = XMLProtocol.Element("FrequencyValue").Value;
         string path = Path.GetDirectoryName(Path.GetDirectoryName(System.IO.Directory.GetCurrentDirectory()));
         System.Reflection.Assembly assembly = Assembly.LoadFrom(path + "../../" + NameSpace + "\\bin\\Debug\\" + NameSpace + ".dll");
         System.Type type = assembly.GetType(NameSpace + '.' + ClassName);
         Protocol protocol = new Protocol((IProtocol)Activator.CreateInstance(type), Convert.ToInt64(int.Parse(FrequencyValue) * GetFrequencyTypeMultiplier(FrequencyType)));
         this.Add(protocol);
     }
Execute(); 

This is the XML:

<Protocols>
  <Protocol>
    <NameSpace>ClassTest</NameSpace>
    <ClassName>Class1</ClassName>
    <FrequencyType>Minute</FrequencyType>
    <FrequencyValue>20</FrequencyValue>
  </Protocol>
</Protocols>

Is there a way to retrieve the assembly without having to "hardcode" the path to the DLL? What is the best practice for that scenario?

\$\endgroup\$
  • \$\begingroup\$ A simple thing: Proper indentation goes a long way, specifically there's no reason for the for-each-loop being indented an extra-level. \$\endgroup\$ – Deduplicator Aug 11 '15 at 18:03
2
\$\begingroup\$

Although this feels very "examplish", here are my thoughts:

Personally, I would rethink how you handle paths currently. As it stands, the directory structure must be very specific: you are provided with some "root" folder, and in that folder you have subfolders, each named after the namespace of the library within it, then a bin folder, then a Debug folder, so an example would be:

C:\Projects\Project1\bin\Debug\Project1.dll
C:\Projects\Project2\bin\Debug\Project2.dll
C:\Projects\ClassTest\bin\Debug\ClassTest.dll
et. al.

If you just wanted to drop a bunch of files in one folder, it's currently not possible.

Why don't you, instead, add the path as a line in the XML file?

<Protocols>
  <Protocol>
    <NameSpace>ClassTest</NameSpace>
    <ClassName>Class1</ClassName>
    <FrequencyType>Minute</FrequencyType>
    <FrequencyValue>20</FrequencyValue>
    <FolderPath>../../ClassTest/bin/Debug/</FolderPath>
  </Protocol>
</Protocols>

The nicety of this is that you can now put your DLL's anywhere. You can use relative, absolute and virtual paths, and you can make them much more dynamic.

C:\Projects\Project1\bin\Debug\Project1.dll
C:\Projects\Project2\bin\Release\Project2.dll
C:\Dean Martin\ClassTest.dll
et. al.

This also means, that if you wish to use the release version of Project1, but the debug version of Project2, you can! Just include the appropriate path name!

This is generally the best-practice for this situation, as the "location" of a DLL file is a configuration aspect, rather than a programme aspect. Only in certain situations (with things like dynamic plugins) would you use a hardcoded (absolute, virtual, or relative: any of the three) path to get to the DLL's. And that would typically be something like Plugins\.


On a separate topic: I would recommend you use the @ prefix for your path strings, to be able to omit escapes:

System.Reflection.Assembly assembly = Assembly.LoadFrom(path + "../../" + NameSpace + @"\bin\Debug\" + NameSpace + ".dll");

This tends to make it more readable. Of course, if you move the file paths to the XML, it won't be a problem. :)

\$\endgroup\$
  • \$\begingroup\$ Before I had the path to the DLL inside the xml file, but my boss said it's not required, that I could do it just with the class name and namespace. So I made that change because I couln't figure out how to make the assembly works without the DLL. I'll probably have to change the string when I won't be in Debug though. The dynamic plugins part you mentioned seems to be my case, I'll see if I can find more about it. \$\endgroup\$ – loli Aug 11 '15 at 18:15
  • 1
    \$\begingroup\$ @loli I would consider reading this MSDN article on the recommended way to build a Plug-In Framework. \$\endgroup\$ – 410_Gone Aug 11 '15 at 18:24
  • 1
    \$\begingroup\$ I got it to work without DLL by reading the MSDN article, thanks ! No more path needed. \$\endgroup\$ – loli Aug 11 '15 at 19:15
  • \$\begingroup\$ @loli Ah, excellent! \$\endgroup\$ – 410_Gone Aug 11 '15 at 19:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.