What is best practice for using one of multiple .dll's

S

Steve Ricketts

I have an application that uses one of a selection of about five .dll's
depending on the user's environment. Each .dll has the same methods and
properties but in this case, uses a different video player. The application
is a conversion from VB6 where the dll name was read from the registry and a
generic object created so the program didn't have to change references to
the object's objects and methods... something like:

videoPlayer = GetString(HKEY_LOCAL_MACHINE, "Software\Velocedge",
"VideoPlayer")
Set videoCtl = CreateObject(videoPlayer)
call videoCtl.PlayerBegin(theURL)

Where video player could be one of:
- dlVideo.clsVideo (windows media)
- dlVideo.clsVideoV (VLC)
- dlVideo.clsVideoH (Helius)
- dlVideo.clsVideoMP (MPlayer)
- dlVideo.clsVideoF (Flash)

This allowed us to simply change the registry value and the application
would use another .dll to (in this case) play video. In the typical user's
case, they would only have one or two of the different types of video
players installed on their computer so we wouldn't want to load a .dll for a
player that didn't exist.

So, my question is, what is the best way to do a similar thing in C#? I've
thought about doing something like:

using dlVideo;
using dlVideoV;
using dlVideoH;
using dlVideoMP;
using dlVideoF;

switch (videoPlayer) {
case dlVideo.clsVideo:
videoCtl = new dlVideo();
break;
case dlVideo.clsVideoV
videoCtl = new dlVideoV();
break;
case dlVideo.clsVideoH
videoCtl = new dlVideoH();
break;
....
}
videoCtl.PlayerBegin(theURL);


But my guess is that there is a much better way. Thanks for any direction
you can provide.

sr
 
T

Tom Shelton

Steve Ricketts laid this down on his screen :
I have an application that uses one of a selection of about five .dll's
depending on the user's environment. Each .dll has the same methods and
properties but in this case, uses a different video player. The application
is a conversion from VB6 where the dll name was read from the registry and a
generic object created so the program didn't have to change references to the
object's objects and methods... something like:

videoPlayer = GetString(HKEY_LOCAL_MACHINE, "Software\Velocedge",
"VideoPlayer")
Set videoCtl = CreateObject(videoPlayer)
call videoCtl.PlayerBegin(theURL)

Where video player could be one of:
- dlVideo.clsVideo (windows media)
- dlVideo.clsVideoV (VLC)
- dlVideo.clsVideoH (Helius)
- dlVideo.clsVideoMP (MPlayer)
- dlVideo.clsVideoF (Flash)

This allowed us to simply change the registry value and the application would
use another .dll to (in this case) play video. In the typical user's case,
they would only have one or two of the different types of video players
installed on their computer so we wouldn't want to load a .dll for a player
that didn't exist.

So, my question is, what is the best way to do a similar thing in C#? I've
thought about doing something like:

using dlVideo;
using dlVideoV;
using dlVideoH;
using dlVideoMP;
using dlVideoF;

switch (videoPlayer) {
case dlVideo.clsVideo:
videoCtl = new dlVideo();
break;
case dlVideo.clsVideoV
videoCtl = new dlVideoV();
break;
case dlVideo.clsVideoH
videoCtl = new dlVideoH();
break;
...
}
videoCtl.PlayerBegin(theURL);


But my guess is that there is a much better way. Thanks for any direction
you can provide.

sr

Well... Since you say all of the objects share the same interface
(same methods/properties) - I would create a dll that defines those
interfaces. For example, in this dll you might create an IVideoControl
interface. This interface would define all of the common methods and
properties. You might also define any common structures - such as
enums in this project as well.

public interface IVideoPlayer
{
void PlayerBegin(string theUrl);
}

Then, your main app and each of your implementation dll's would
reference this common interfaces dll. Each of the implementation dll's
would create thier main video player class so that it implemented this
itnerface:

// in dlvideo
public class WMPVideo : IVideoPlayer
{
public void PlayerBegin (string theUrl)
{
// wmp implementation
}
}

// in dlvideov
public class VlcVideo : IVideoPlayer
{
void PlayerBegin (string theUrl)
{
// vlc implementation
}
}

etc.

Then, in your main app you can use a config file or settings, etc to
determine at runtime which dll to load. You can dynamically load the
assembly using one of the Assembly.Load overloads. Once it's loaded,
then you can enumerate the types in it using Assemly.GetTypes and when
you find one that implementes IVideoPlayer then you can instantiate
that class using assembly.CreateInstance... I would wrap all of this in
some sort of factory method:

IVideoPlayer player = PlayerFactory.GetVideoPlayer();
player.PlayerBegin (theUrl);

That would be the basic way... Of course, if you allow the user to
change players on the fly, etc. You'll probably want to look into
using the System.AddIn namespace stuff - dynamic loading is easy, but
being able to dynamically unload something is not so easy :)
 
S

Steve Ricketts

Yep... there is a better way! Thanks for the description. No need to
change on the fly here. Once the application is established for a given
user, they will always (theoretically) use the same player. At least they
won't while the application is executing.

I haven't used the Factory method approach yet, but I know enough about it
that it sounds perfect. Thanks for the response, very helpful.

sr
 
Top