可选的依赖关系处理(C#) [英] Dealing with optional dependencies (C#)
问题描述
我们有哪些可选TFS中集成的应用,但是作为集成是可选的我明显的不希望将所有的机器所需要的TFS组件作为一项要求
We have an app which optionally integrates with TFS, however as the integration is optional I obviously don't want to have all machine need the TFS assemblies as a requirement.
我应该怎么办?
- 它是确定由我来引用TFS库在我的主要组件和公正,确保当我使用TFS集成,我只引用TFS相关的对象。
-
或者更安全的选择将是引用TFS库在某些单独的TFSWrapper组装:
- Is it ok for me to reference the TFS libraries in my main assemblies and just make sure that I only reference TFS related objects when I'm using TFS integration.
Alternatively the safer option would be to reference the TFS libraries in some separate "TFSWrapper" assembly:
一。它是那么好,我直接引用该程序集(再次只要我小心我所说的)
a. Is it then ok for me to reference that assembly directly (again as long as I'm careful about what I call)
乙。我反而是暴露了一组接口,为我TFSWrapper组装来实现,然后在需要时使用反射实例化的对象。
b. Should I instead be exposing a set of interfaces for my TFSWrapper assembly to implement, and then instantiate those objects using reflection when required.
1,似乎有风险的我,在另一面2B似乎过度的顶部 - 我本质上可以构建一个插件系统
1 seems risky to me, on the flip side 2b seems over-the-top - I would essentially be building a plug-in system.
当然,必有是一个简单的方法。
Surely there must be a simpler way.
推荐答案
最安全的方式(即不使你的应用程序中的错误,最简单的方法)可能是因为。如下
The safest way (i.e. the easiest way to not make a mistake in your application) might be as follows.
请哪个抽象你TFS的使用,例如接口:
Make an interface which abstracts your use of TFS, for example:
interface ITfs
{
bool checkout(string filename);
}
写它实现了使用TFS这个接口的类:
Write a class which implements this interface using TFS:
class Tfs : ITfs
{
public bool checkout(string filename)
{
... code here which uses the TFS assembly ...
}
}
写
class NoTfs : ITfs
{
public bool checkout(string filename)
{
//TFS not installed so checking out is impossible
return false;
}
}
有地方一个单:
Have a singleton somewhere:
static class TfsFactory
{
public static ITfs instance;
static TfsFactory()
{
... code here to set the instance
either to an instance of the Tfs class
or to an instance of the NoTfs class ...
}
}
的
现在,只有一个地方,需要小心(即TfsFactory构造函数);其余的代码可以调用您的TfsFactory.instance的ITFS方法,不知道是否安装TFS的。
Now there's only one place which needs to be careful (i.e. the TfsFactory constructor); the rest of your code can invoke the ITfs methods of your TfsFactory.instance without knowing whether TFS is installed.
要回答下方最近的评论:
To answer recent comments below:
根据我的测试(我不知道这是否是'定义的行为)有异常时,(只要)你抛出一个叫方法,它依赖于丢失的组件。因此,在汇编封装代码 - 这-依赖 - 上的缺失组装至少在一个单独的方法(或一个单独的类)是很重要的。
According to my tests (I don't know whether this is 'defined behaviour') an exception is thrown when (as soon as) you call a method which depends on the missing assembly. Therefore it's important to encapsulate your code-which-depends-on-the-missing-assembly in at least a separate method (or a separate class) in your assembly.
例如,如果通话组件缺少以下将不会加载:
For example, the following won't load if the Talk assembly is missing:
using System;
using OptionalLibrary;
namespace TestReferences
{
class MainClass
{
public static void Main(string[] args)
{
if (args.Length > 0 && args[0] == "1") {
Talk talk = new Talk();
Console.WriteLine(talk.sayHello() + " " + talk.sayWorld() + "!");
} else {
Console.WriteLine("2 Hello World!");
}
}
}
}
的
以下将加载:
The following will load:
using System;
using OptionalLibrary;
namespace TestReferences
{
class MainClass
{
public static void Main(string[] args)
{
if (args.Length > 0 && args[0] == "1") {
foo();
} else {
Console.WriteLine("2 Hello World!");
}
}
static void foo()
{
Talk talk = new Talk();
Console.WriteLine(talk.sayHello() + " " + talk.sayWorld() + "!");
}
}
}
这是测试结果(使用Windows MSVC#2010和.NET):
These are the test results (using MSVC# 2010 and .NET on Windows):
C:\github\TestReferences\TestReferences\TestReferences\bin\Debug>TestReferences.exe
2 Hello World!
C:\github\TestReferences\TestReferences\TestReferences\bin\Debug>TestReferences.exe 1
Unhandled Exception: System.IO.FileNotFoundException: Could not load file or assembly 'OptionalLibrary, Version=1.0.0.0,
Culture=neutral, PublicKeyToken=null' or one of its dependencies. The system cannot find the file specified.
at TestReferences.MainClass.foo()
at TestReferences.MainClass.Main(String[] args) in C:\github\TestReferences\TestReferences\TestReferences\Program.cs:
line 11
C:\github\TestReferences\TestReferences\TestReferences\bin\Debug>
这篇关于可选的依赖关系处理(C#)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!