プラグインクラス属性
Namespace: fvalgcliAssembly: fvalgcli (in fvalgcli.dll) Version: 3.1.0.0 (3.1.0.11)
Syntax
C# |
---|
public class FvPluginClassAttribute : Attribute |
Visual Basic |
---|
Public Class FvPluginClassAttribute Inherits Attribute |
Remarks
実行対象のクラスを指定する属性です。
アセンブリとクラスの関係は 1:N であることを想定しています。
ユニットテストやベンチマークを対象にします。
各属性とアセンブリやクラスの関係:
属性 | アセンブリとの関係 | クラスとの関係 | 説明 |
---|---|---|---|
FvPluginSetupAttribute | 1 | 1 | 初期化処理を保有しているクラス及びメソッド |
FvPluginTearDownAttribute | 1 | 1 | 解放処理を保有しているクラス及びメソッド |
FvPluginClassAttribute | N | 1 | 実行対象の処理を保有するクラス |
FvPluginPrepareAttribute | N | 1 | 処理前の準備 |
FvPluginRestoreAttribute | N | 1 | 処理後の復元 |
FvPluginExecuteAttribute | N | N | 実行対象の処理 |
Examples
トピック:
属性を読み込んで実行する処理:
初期化処理と解放処理:
実行対象の処理を保有するクラス:
実行結果:
属性を読み込んで実行する処理:
ここでは GetExecutingAssembly で現在のアセンブリを取得してクラスとメソッドを抽出していますが、 アセンブリを動的ロードする場合は Load や LoadFile を使用します。
C# | Copy |
---|---|
// $Revision: 1.1 $ using System; using System.Collections.Generic; using System.Text; using System.Reflection; using System.Diagnostics; using fvalgcli; namespace User.SampleCode { /// <summary> /// ホストクラス. /// </summary> class Host { /// <summary> /// エントリポイント. /// </summary> /// <param name="args"></param> public static void _Main(string[] args) { // 初期化. Setup(); // 実行. Execute(); // 解放. TearDown(); } /// <summary> /// 初期化. /// </summary> public static void Setup() { Assembly asm = Assembly.GetExecutingAssembly(); Type[] types = asm.GetTypes(); foreach (Type type in types) { // [FvPluginSetup] 属性が付加されたクラスか否かの検査. object[] attrs = type.GetCustomAttributes(typeof(FvPluginSetupAttribute), true); if (attrs.Length == 0) continue; // メソッド情報の抽出及び実行. // ※注) static 関数である前提で関数を呼び出しています. MethodInfo[] methods = type.GetMethods(); foreach (MethodInfo method in methods) { attrs = method.GetCustomAttributes(typeof(FvPluginSetupAttribute), true); if (attrs.Length > 0) { Console.WriteLine(type.Name + "." + method.Name); method.Invoke(null, null); } } } } /// <summary> /// 解放. /// </summary> public static void TearDown() { Assembly asm = Assembly.GetExecutingAssembly(); Type[] types = asm.GetTypes(); foreach (Type type in types) { // [FvPluginTearDown] 属性が付加されたクラスか否かの検査. object[] attrs = type.GetCustomAttributes(typeof(FvPluginTearDownAttribute), true); if (attrs.Length == 0) continue; // メソッド情報の抽出及び実行. // ※注) static 関数である前提で関数を呼び出しています. MethodInfo[] methods = type.GetMethods(); foreach (MethodInfo method in methods) { attrs = method.GetCustomAttributes(typeof(FvPluginTearDownAttribute), true); if (attrs.Length > 0) { Console.WriteLine(type.Name + "." + method.Name); method.Invoke(null, null); } } } } /// <summary> /// 実行. /// </summary> public static void Execute() { ResolveEventHandler asm_resolving = new ResolveEventHandler(AssemblyResolving); ResolveEventHandler type_resolving = new ResolveEventHandler(TypeResolving); try { AppDomain.CurrentDomain.AssemblyResolve += asm_resolving; AppDomain.CurrentDomain.TypeResolve += type_resolving; Assembly asm = Assembly.GetExecutingAssembly(); Type[] types = asm.GetTypes(); foreach (Type type in types) { // [FvPluginClass] 属性が付加されたクラスか否かの検査. object[] attrs = type.GetCustomAttributes(typeof(FvPluginClassAttribute), true); if (attrs.Length == 0) continue; List<MethodInfo> prepares = new List<MethodInfo>(); List<MethodInfo> executes = new List<MethodInfo>(); List<MethodInfo> restores = new List<MethodInfo>(); // メソッド情報の抽出. MethodInfo[] methods = type.GetMethods(); foreach (MethodInfo method in methods) { attrs = method.GetCustomAttributes(typeof(FvPluginPrepareAttribute), true); if (attrs.Length > 0) prepares.Add(method); attrs = method.GetCustomAttributes(typeof(FvPluginExecuteAttribute), true); if (attrs.Length > 0) executes.Add(method); attrs = method.GetCustomAttributes(typeof(FvPluginRestoreAttribute), true); if (attrs.Length > 0) restores.Add(method); } object instance = Activator.CreateInstance(type); // 処理前の準備. foreach (MethodInfo method in prepares) { Console.WriteLine(type.Name + "." + method.Name); method.Invoke(instance, null); } // 処理. foreach (MethodInfo method in executes) { Console.WriteLine(type.Name + "." + method.Name); Stopwatch watch = new Stopwatch(); watch.Start(); method.Invoke(instance, null); watch.Stop(); Console.WriteLine("{0:0.000} msec", watch.ElapsedMilliseconds); } // 処理後の復元. foreach (MethodInfo method in restores) { Console.WriteLine(type.Name + "." + method.Name); method.Invoke(instance, null); } } } finally { AppDomain.CurrentDomain.AssemblyResolve -= asm_resolving; AppDomain.CurrentDomain.TypeResolve -= type_resolving; } } /// <summary> /// デシリアライズ時にアセンブリの解決が失敗したときに発生します。(seealso:AppDomain.CurrentDomain.AssemblyResolve) /// </summary> /// <param name="sender">送信元</param> /// <param name="args">アセンブリ名</param> /// <returns> /// 指定されたアセンブリ名に該当するアセンブリを返します。 /// </returns> public static Assembly AssemblyResolving(object sender, ResolveEventArgs args) { string name = args.Name.Split(',')[0]; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { if (name == assembly.FullName.Split(',')[0]) return assembly; } return null; } /// <summary> /// Type.GetType() で型の解決が失敗したときに発生します。 /// </summary> /// <param name="sender"></param> /// <param name="args"></param> /// <returns> /// 見つかったアセンブリを返します。 /// </returns> public static Assembly TypeResolving(object sender, ResolveEventArgs args) { string name = args.Name.Split(',')[0]; Assembly[] assemblies = AppDomain.CurrentDomain.GetAssemblies(); foreach (Assembly assembly in assemblies) { Type[] types = assembly.GetTypes(); foreach (Type type in types) { if (name == type.FullName) return assembly; } } return null; } } } |
初期化処理と解放処理:
アセンブリロード時に実行する初期化処理やアンロード時に実行する解放処理を記述します。
C# | Copy |
---|---|
using System; using System.Collections.Generic; using System.Text; using fvalgcli; namespace User.SampleCode { /// <summary> /// テスト対象1: 初期化と解放を行います. /// </summary> [FvPluginSetup] [FvPluginTearDown] public class TestClass1 { /// <summary> /// 初期化. /// </summary> [FvPluginSetup] public static void Setup() { api.fnFIE_setup(); } /// <summary> /// 解放. /// </summary> [FvPluginTearDown] public static void TearDown() { api.fnFIE_teardown(); } } } |
実行対象の処理を保有するクラス:
ユニットテストやベンチマークを記述します。
C# | Copy |
---|---|
using System; using System.Collections.Generic; using System.Text; using fvalgcli; namespace User.SampleCode { /// <summary> /// テスト対象2: 実行対象の処理を保有しています. /// </summary> [FvPluginClass] public class TestClass2 : IDisposable { /// <summary> /// コンストラクタ. /// </summary> public TestClass2() { } /// <summary> /// テスト対象の画像. /// </summary> private FHANDLE TestImage = IntPtr.Zero; /// <summary> /// 実行前の準備. /// </summary> [FvPluginPrepare] public void Initialize() { // テスト対象の画像ファイルの読み込み. FHANDLE hImage = IntPtr.Zero; api.fnFIE_load_img_file("./testimage_rgb.png", ref hImage, f_color_img_type.F_COLOR_IMG_TYPE_UC8); this.TestImage = hImage; } /// <summary> /// 実行前の復元. /// </summary> [FvPluginRestore] public virtual void Dispose() { TestImage.Dispose(); } /// <summary> /// テスト1 /// </summary> [FvPluginExecute] public void Test1() { FHANDLE hsrc = this.TestImage; int type = api.fnFIE_img_get_type(hsrc); int channels = api.fnFIE_img_get_channels(hsrc); int width = api.fnFIE_img_get_width(hsrc); int height = api.fnFIE_img_get_height(hsrc); Console.WriteLine("type = {0}", (f_imgtype)type); Console.WriteLine("channels = {0}", channels); Console.WriteLine("width = {0}", width); Console.WriteLine("height = {0}", height); if (type == (int)f_imgtype.F_IMG_UC8) { // 各チャネルの積算値. for (int ch = 0; ch < channels; ch++) { double sum = 0; SIZE_T step = api.fnFIE_img_get_step(hsrc) * sizeof(byte); UCHAR_PTR adrs = api.fnFIE_img_get_ch_adrs(hsrc, ch); for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) sum += adrs[x]; adrs += step; } Console.WriteLine("ch{1}.sum = {0}", sum, ch); } } } /// <summary> /// テスト2 /// </summary> [FvPluginExecute] public void Test2() { FHANDLE target = IntPtr.Zero; FHANDLE test = IntPtr.Zero; try { // 処理. int width = api.fnFIE_img_get_width(TestImage); int height = api.fnFIE_img_get_height(TestImage); target = api.fnFIE_img_root_alloc(f_imgtype.F_IMG_UC8, 1, width, height); api.fnFIE_img_rgb_to_gray(TestImage, target, 0.299, 0.587, 0.114, 0); // 比較. bool result = false; api.fnFIE_load_img_file("./testimage_uc8.png", ref test, f_color_img_type.F_COLOR_IMG_TYPE_UC8); api.fnFIE_img_compare(target, test, ref result); if (result == false) throw new FvException(f_err.F_ERR_INVALID_IMAGE); Console.WriteLine("completed."); } catch(System.Exception ex) { Console.WriteLine(ex.Message); } finally { target.Dispose(); test.Dispose(); } } } } |
実行結果:
TestClass1.Setup TestClass2.Initialize TestClass2.Test1 type = F_IMG_UC8 channels = 3 width = 320 height = 240 ch0.sum = 12070920 ch1.sum = 12222679 ch2.sum = 12060206 9.000 msec TestClass2.Test2 completed. 4.000 msec TestClass2.Dispose TestClass1.TearDown
Inheritance Hierarchy
System..::..Object
System..::..Attribute
fvalgcli..::..FvPluginClassAttribute
System..::..Attribute
fvalgcli..::..FvPluginClassAttribute