機能が異なるいくつかのアセンブリを含むライブラリがあります。このライブラリは、クライアント向けに開発するフロントエンド プロジェクトで使用します。ライブラリ内で特定のタスク/メソッドを実行したいが、そのメソッドの実装はフロントエンドにある必要があるとします。
つまり、ライブラリ内のクラス X はライブラリ内のクラス Y のメソッド A を呼び出しますが、メソッド A はライブラリ外で実装する必要があります。どのように?
機能が異なるいくつかのアセンブリを含むライブラリがあります。このライブラリは、クライアント向けに開発するフロントエンド プロジェクトで使用します。ライブラリ内で特定のタスク/メソッドを実行したいが、そのメソッドの実装はフロントエンドにある必要があるとします。
つまり、ライブラリ内のクラス X はライブラリ内のクラス Y のメソッド A を呼び出しますが、メソッド A はライブラリ外で実装する必要があります。どのように?
ClassY を Abstract クラスとして定義し、コンシューマーが Abstract として定義されたメソッドの実装を提供することを要求します。ClassY ベースで定義されたロジックは、すべての派生クラスに共通であり、ClassY ベースで「抽象」として定義されたメソッドは、派生クラスごとに実装する必要があります。これをハックしたのは単なる例であるため、実際のコードがベスト プラクティスを表しているとは主張しません。
抽象基本クラス:
public abstract class AbstractLibraryClassY
{
private static int _multiplier = 0;
public abstract int MethodA(int SomeParam);
// A simple example Property defined and implemented on the Abstract base class:
public int Multiplier
{
get { return _multiplier; }
set { _multiplier = value; }
}
private void someclassYImplementationStuff()
{
// Other implementation code . . .
}
}
ClassY の 2 つの可能な実装:
public class ConcreteClassYImplementationOne : AbstractLibraryClassY
{
public override int MethodA(int SomeParam)
{
return SomeParam * this.Multiplier;
}
}
public class ConcreteClassYImplementationTwo : AbstractLibraryClassY
{
public override int MethodA(int SomeParam)
{
return SomeParam * this.Multiplier + 5;
}
}
クラス X、クラス Y のインスタンスを消費:
public class LibraryClassX
{
public int methodCallsClassYMethodA(AbstractLibraryClassY ImplementedClassY)
{
ImplementedClassY.Multiplier = 2;
return ImplementedClassY.MethodA(100);
}
}
クラス X を使用して ClassY の各実装を順番に使用する簡単なデモ:
public class Consumer1
{
public void ConsumeClassX()
{
// Some hokey, arbitrary inputs:
int MyInput = 200;
int MyMultiplier = 2;
// Consume Library Class Y using ConcreteClassYImplementationOne:
AbstractLibraryClassY InstanceOf = new ConcreteClassYImplementationOne();
InstanceOf.Multiplier = MyMultiplier;
// Will output 400, per implementation defined in ConcreteClassYImplementationOne:
Console.WriteLine("Output = " + InstanceOf.MethodA(MyInput).ToString());
// Consume Library Class Y using ConcreteClassYImplementationTwo:
InstanceOf = new ConcreteClassYImplementationTwo();
InstanceOf.Multiplier = MyMultiplier;
// Will output 405, per implementation defined in ConcreteClassYImplementationTwo:
Console.WriteLine("Output = " + InstanceOf.MethodA(MyInput).ToString());
}
}
それが役立つことを願っています。コメンターの提案 re: Dependency Injection も調べてください。私は今それを調べているところです(そして、それは私が今説明したことかもしれません-よくわかりません、調査する必要があります!
ライブラリからデリゲートを公開し、コンシューマーが独自の実装を指すように設定できるようにします。
例:
public delegate void DoWorkDelegate(CustomWorkParameters p);
public DoWorkDelegate DoWorkCallback
{
get
{
return _workCallback;
}
set
{
_workCallback = value;
}
}
ライブラリの後半で、実際に作業を行う必要がある場合:
private void DoWorkInternal()
{
//Some work here
//Check if caller set the callback
if(_workCallback != null)
{
_workCallback(localWorkParameters);
}
else
{
//throw exception
}
//Some more work here
}
消費者は、デリゲートの署名を尊重するメソッドを持っている必要があり、初期化フェーズでライブラリに渡すだけです。