出力処理を実行時に動的に適用するサンプル
同じ事が実現できるライブラリはたくさんあると思うが、ここは自前で簡単に実装してみる。 やることは以下の通り。
以下コード。
インターフェースたち (Samples.Common)(共通ライブラリ)
namespace Samples.Common
{
using System;
using System.Collections.Generic;
using System.Linq;
public interface IExecutable
{
void Execute();
}
public interface IOutputManager
{
void Write(object data);
void WriteLine(object data);
}
}
出力管理クラス (Samples.Common)(共通ライブラリ)
namespace Samples.Common
{
using System;
using System.Collections.Generic;
using System.Linq;
public static class Output
{
private static IOutputManager _Manager;
public static void SetOutputManager(IOutputManager manager)
{
_Manager = manager;
}
public static void Write(object data)
{
Defence();
_Manager.Write(data);
}
public static void WriteLine(object data)
{
Defence();
_Manager.WriteLine(data);
}
private static void Defence()
{
if (_Manager == null)
{
throw new InvalidOperationException("No OutputManager was found. please call SetOutputManager(IOutputManager) before your first access");
}
}
}
}
サンプルクラス (Samples.Lib)(サンプルライブラリ)
namespace Samples.Lib
{
using System;
using System.Collections.Generic;
using System.Linq;
using Samples.Common;
public class Sample01 : IExecutable
{
public void Execute()
{
Output.WriteLine("hello world");
}
}
}
クライアントアプリ (Samples.Cui)(コンソールアプリ)
namespace Samples.Cui
{
using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Samples.Common;
class Program
{
static void Main()
{
Output.SetOutputManager(new CuiOutputManager());
// (1) アセンブリを直接ロードしてインスタンス作成
var asm = Assembly.Load("Samples.Lib");
var sample = (IExecutable) asm.CreateInstance("Samples.Lib.Sample01");
// (2) Activator経由でアセンブリのロードとインスタンス作成
//var sample = (IExecutable) Activator.CreateInstance("Samples.Lib", "Samples.Lib.Sample01").Unwrap();
sample.Execute();
Console.WriteLine("press any key to exit...");
Console.ReadKey();
}
}
public class CuiOutputManager : IOutputManager
{
public void Write(object data)
{
Console.Write(data);
}
public void WriteLine(object data)
{
Console.WriteLine(data);
}
}
}