开发者

Conditionally including code based on the existence of a class

I have two function that do the exact same thing in two different ways. Each uses a different class to accomplish the task:

void functionA()
{
  ClassA a = new ClassA();
  a.doWork();
}

void functionB()
{
  ClassB b = new ClassB();
  b.doSom开发者_StackOverflow中文版ething();
}

this is all in a self contained HttpHandler that can be dropped in any project and work - At least thats the goal. FunctionA would be the preferred way of doing things, FunctionB is a fallback. ClassA might not exist in a given project, ClassB will always exist.

Is there a way at runtime to detect is ClassA exists an use functionA and if not use fcuntionB. Also is there a way to compile this if ClassA doesn't exist? Can I do this with pre-processor stuff (i.e. can I tell at compile time which to include?)


Typically, situations like this are much better handled via Inversion of Control than trying to determine the existence of a class.

Instead of looking for "ClassA" and "ClassB", it would be a better option to provide 2 interfaces that could be implemented. You could then use Dependency Injection to attempt to inject an instance of IInterfaceA, and if it fails, use an instance of IInterfaceB instead.

A good articles to read might be Martin Fowler's article on IoC. Also, you may want to look at the Managed Extensibility Framework (now included in .NET 4) which makes this very easy in C#.


If you must do it with the preprocessor #if and #define directives, then in ClassA add

#define ClassA

In your HttpHandler add

#if ClassA
  void function() { ClassA a = new ClassA(); a.doWork(); }
#else
  void function() { ClassB b = new ClassB(); b.doSomething(); }
#endif

If possible it would be better to use dependency injection and pass it into the constructor of the HttpHandler.


You could split your class into two files using the partial keyword:

// MyClass.cs -- include this into every project
public partial class MyClass {
    public void functionB() { ClassB b = new ClassB(); b.doSomething(); }
}

// MyClass.functionA.cs -- include only into projects that have ClassA
public partial class MyClass {
    public void functionA() { ClassA a = new ClassA(); a.doWork(); }
}

We do this a few places in our code. I like the "BaseName.Specialty.cs" naming convention, because Solution Explorer will automatically show MyClass.functionA.cs as a sub-node nested under MyClass.cs, the same way it does with .designer.cs files.


You can use reflection (http://msdn.microsoft.com/en-us/library/f7ykdhsy(v=vs.71).aspx). Specifically System.Reflection.Module which can return a list of available types in the module (http://msdn.microsoft.com/en-US/library/system.reflection.module.gettypes(v=VS.80).aspx). I would imagine you can simply cast once you know which type exists.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜