MAGç»åãã¼ã
åçªã«PC98æ代ã«ãã使ããã¦ããMAGç»åå½¢å¼ãã¡ã¤ã«ãèªã¿è¾¼ãããã°ã©ã ãC#ã«ç§»æ¤ãã¦ã¿ã¾ãããï¼ï¼ï¼åã®ç»åã§ãã試ãã¦ãªãã®ã§ãã°ãããããã
// è¬è¾ // MITH(T.Saito)æ°ã®ï¼·ï¼¡ï¼¢âï¼³ç¨ãã«ãã°ã©ãã£ãã¯ãã¼ã WMLã®ã½ã¼ã¹ãåèã«ããã¦ããã ãã¾ããã using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Runtime.InteropServices; using System.Text; /// <summary> /// MAGå½¢å¼ç»åãã¼ãã /// </summary> public static class MagFile { private static readonly sbyte[] FlagX = {0, -1, -2, -4, 0, -1, 0, -1, -2, 0, -1, -2, 0, -1, -2, 0}; private static readonly sbyte[] FlagY = {0, 0, 0, 0, -1, -1, -2, -2, -2, -4, -4, -4, -8, -8, -8, 0}; [StructLayout(LayoutKind.Sequential, Pack = 1)] private unsafe struct MagFileHeader { private fixed byte mgHeader [8]; private fixed byte mgMachine [4]; private fixed byte mgUser [8]; } [StructLayout(LayoutKind.Sequential, Pack = 1)] private struct MagHeader { private readonly byte mgHeader; private readonly byte mgMachine; private readonly byte mgSystem; public readonly byte mgScreenmode; public readonly ushort mgStartX; public readonly ushort mgStartY; public readonly ushort mgEndX; public readonly ushort mgEndY; public readonly uint mgFlagA_offset; public readonly uint mgFlagB_offset; public readonly uint mgFlagBSize; public readonly uint mgPixelD_offst; public readonly uint mgPixelDSize; } private static unsafe void ReadMagFileHeader(Stream stream, out MagFileHeader magFileHeader) { fixed (void* p = &magFileHeader) { var buf = new byte[sizeof (MagFileHeader)]; stream.Read(buf, 0, buf.Length); Marshal.Copy(buf, 0, (IntPtr) p, buf.Length); } } private static unsafe void ReadMagHeader(Stream stream, out MagHeader magHeader) { fixed (void* p = &magHeader) { var buf = new byte[sizeof (MagHeader)]; stream.Read(buf, 0, buf.Length); Marshal.Copy(buf, 0, (IntPtr) p, buf.Length); } } private static string ReadComment(Stream stream) { var bytes = new List<byte>(); var data = stream.ReadByte(); while (data != 0x1a) { bytes.Add((byte) data); data = stream.ReadByte(); } return Encoding.GetEncoding(932).GetString(bytes.ToArray()); } private static PixelFormat GetPixelFormat(MagHeader magHeader) { return (magHeader.mgScreenmode & 0x80) == 0x80 ? PixelFormat.Format8bppIndexed : PixelFormat.Format4bppIndexed; } private static Bitmap CreateBitmap(MagHeader magHeader) { return new Bitmap(magHeader.mgEndX + 1, magHeader.mgEndY + 1, GetPixelFormat(magHeader)); } private static IEnumerable<Color> ReadPalette(Stream stream, MagHeader magHeader) { var n = (magHeader.mgScreenmode & 0x80) == 0x80 ? 256 : 16; var palette = new byte[n*3]; stream.Read(palette, 0, palette.Length); for (var i = 0; i < n; ++i) { var g = palette[i*3 + 0]; var r = palette[i*3 + 1]; var b = palette[i*3 + 2]; yield return Color.FromArgb(0xff, r, g, b); } } private static void SetPalette(Bitmap bitmap, IEnumerable<Color> colors) { var i = 0; var colorPalette = bitmap.Palette; foreach (var color in colors) colorPalette.Entries[i++] = color; bitmap.Palette = colorPalette; } private static int GetStartX(MagHeader magHeader) { var n = (magHeader.mgScreenmode & 0x80) == 0x80 ? 256 : 16; int startx; if (n == 256) startx = magHeader.mgStartX/4*4; else startx = magHeader.mgStartX/8*8; return startx; } private static int GetPixelSizeX(MagHeader magHeader) { var n = (magHeader.mgScreenmode & 0x80) == 0x80 ? 256 : 16; int xsize; int startx; if (n == 256) { startx = magHeader.mgStartX/4*4; xsize = ((magHeader.mgEndX + 4)/4*4 - startx); } else { startx = magHeader.mgStartX/8*8; xsize = ((magHeader.mgEndX + 8)/8*8 - startx + 1)/2; } return xsize; } private static int GetFlagASize(MagHeader magHeader) { int xsize = GetPixelSizeX(magHeader); var x = xsize/4; var ysize = magHeader.mgEndY - magHeader.mgStartY + 1; return (x*ysize + 7)/8; } private static void ReadFlagA(Stream stream, MagHeader magHeader, long startPos, byte[] flagA) { stream.Seek(startPos + magHeader.mgFlagA_offset, SeekOrigin.Begin); stream.Read(flagA, 0, flagA.Length); } private static void ReadFlagB(Stream stream, ref uint left, ref uint xpoint, long startPos, byte[] flagB) { stream.Seek(startPos + xpoint, SeekOrigin.Begin); if (left > 0x8000) { stream.Read(flagB, 0, 0x8000); xpoint += 0x8000; left -= 0x8000; } else { stream.Read(flagB, 0, 0x8000); left = 0; } } /// <summary> /// ãã¯ã»ã«åä½ã®èªã¿è¾¼ã¿ã /// <remarks>MAGãã©ã¼ãããã§ã¯2byteåä½ããã¯ã»ã«ã¨å¼ã¶ã1ãã¯ã»ã«ã«ã¯16è²ã®å ´å4ãããã256è²ãªã2ããããããã¯ããã¦ããã</remarks> /// </summary> /// <param name="stream"></param> /// <param name="left"></param> /// <param name="xpoint"></param> /// <param name="startPos"></param> /// <param name="pixel"></param> private static void ReadMagPixel(Stream stream, ref uint left, ref uint xpoint, long startPos, ushort[] pixel) { stream.Seek(startPos + xpoint, SeekOrigin.Begin); var tmp = new byte[0x8000]; if (left > 0x8000) { stream.Read(tmp, 0, 0x8000); xpoint += 0x8000; left -= 0x8000; } else { stream.Read(tmp, 0, 0x8000); left = 0; } unsafe { fixed (void* p = &pixel[0]) { Marshal.Copy(tmp, 0, (IntPtr) p, tmp.Length); } } } /// <summary> /// MAGç»åã®ãã¼ãã /// </summary> /// <param name="stream">MAGç»åã®ã¹ããªã¼ã ã</param> /// <returns>ããããããã</returns> public static Bitmap Load(Stream stream) { MagFileHeader magFileHeader; ReadMagFileHeader(stream, out magFileHeader); var comment = ReadComment(stream); // ã³ã¡ã³ããèªã¿é£ã°ããä½ç½®ãMAGãããã®éå§ä½ç½®ã var startPos = stream.Position; // MAGãããèªã¿è¾¼ã¿ã MagHeader magHeader; ReadMagHeader(stream, out magHeader); // åºåç¨ããããããã®ä½æã var bitmap = CreateBitmap(magHeader); // ã¨ããããã¿ã°ã«ã³ã¡ã³ããå ¥ããã bitmap.Tag = comment; // ãã¬ããã®è¨å®ã var colors = ReadPalette(stream, magHeader); SetPalette(bitmap, colors); // ãã©ã°Aãèªã¿è¾¼ãã var flagA = new byte[GetFlagASize(magHeader)]; ReadFlagA(stream, magHeader, startPos, flagA); // ãã©ã°Bãèªã¿è¾¼ãã var flagB = new byte[0x8000]; var leftFlagB = magHeader.mgFlagBSize; var offsetFlagB = magHeader.mgFlagB_offset; ReadFlagB(stream, ref leftFlagB, ref offsetFlagB, startPos, flagB); // ãã¯ã»ã«ãèªã¿è¾¼ãã var pixel = new ushort[0x8000/sizeof (ushort)]; var leftPixel = magHeader.mgPixelDSize; var offsetPixel = magHeader.mgPixelD_offst; ReadMagPixel(stream, ref leftPixel, ref offsetPixel, startPos, pixel); // ãã©ã°A,Bãããã¯ã»ã«ãã¼ã¿ã復å ã unsafe { var pixelSizeX = GetPixelSizeX(magHeader); var flagBmap = new byte[pixelSizeX]; var line = new ushort[pixelSizeX*8]; fixed (byte* p1 = &flagA[0]) fixed (ushort* p2 = &line[0]) fixed (byte* p3 = &flagBmap[0]) { var startx = GetStartX(magHeader); var pFlagA = p1; var pline = p2; var p = 0; var w = 0; var ibit = 0x80; var curFlagA = *pFlagA++; var j = 15; for (int y = magHeader.mgStartY; y <= magHeader.mgEndY; ++y) { var flag = new int[16]; ++j; for (var i = 0; i < flag.Length; ++i) flag[i] = FlagX[i]*2 + ((FlagY[i] + j) & 0xf)*pixelSizeX; if (j == 16) j = 0; var pFlagBmap = p3; var ftmp = flag[0]; var cline = pline + (ftmp/2); for (var x = 0; x < pixelSizeX;) { if ((curFlagA & ibit) != 0) { if (p >= 0x8000) { ReadFlagB(stream, ref leftFlagB, ref offsetFlagB, startPos, flagB); p = 0; } *pFlagBmap ^= flagB[p++]; } ibit >>= 1; if (ibit == 0) { ibit = 0x80; curFlagA = *pFlagA++; } var fr = *pFlagBmap; pFlagBmap++; if ((fr >> 4) == 0) { if (w >= 0x8000) { ReadMagPixel(stream, ref leftPixel, ref offsetPixel, startPos, pixel); w = 0; } line[(ftmp + x)/2] = pixel[w/2]; w += 2; } else { line[(ftmp + x)/2] = line[(flag[fr >> 4] + x)/2]; } x += 2; if ((fr & 0x0f) == 0) { if (w >= 0x8000) { ReadMagPixel(stream, ref leftPixel, ref offsetPixel, startPos, pixel); w = 0; } line[(ftmp + x)/2] = pixel[w/2]; w += 2; } else { line[(ftmp + x)/2] = line[(flag[fr & 0xf] + x)/2]; } x += 2; } // ï¼ã©ã¤ã³åãããããããã«æ¸ãåºãã var b = new byte[pixelSizeX]; for (var i = 0; i < pixelSizeX/2; i++) { var c = cline[i]; b[i*2] = (byte) (c & 0xff); b[i*2 + 1] = (byte) ((c >> 8) & 0xff); } var dst = bitmap.LockBits(new Rectangle(magHeader.mgStartX, y, bitmap.Width, 1), ImageLockMode.WriteOnly, bitmap.PixelFormat); Marshal.Copy(b, magHeader.mgStartX - startx, dst.Scan0, bitmap.PixelFormat == PixelFormat.Format8bppIndexed ? bitmap.Width : bitmap.Width/2); bitmap.UnlockBits(dst); } } } return bitmap; } /// <summary> /// MAGç»åã®ãã¼ãã /// </summary> /// <param name="path">MAGç»åãã¡ã¤ã«åã</param> /// <returns>ããããããã</returns> public static Bitmap Load(string path) { using (var fl = new FileStream(path, FileMode.Open)) { return Load(fl); } } } /* 使ãæ¹ * * var bmp = MagFile.Load(magfile); * */
MEFã§ãªã¼ãã³ã¸ã§ããªãã¯åãã¨ã¯ã¹ãã¼ã
MefContribã«ã¯ã¸ã§ããªãã¯ç¨ã®GenericCatalogã¯ã©ã¹ãããã¾ããããã使ãã¨ãªã¼ãã³ã¸ã§ããªãã¯åãã¨ã¯ã¹ãã¼ããããã¨ãã§ãã¾ãããã ãããã¥ã¡ã³ãä¸è¶³ãªä¸ã«ãã¡ãã£ã¨çãããããã§ãã
å ¬éããã¤ã³ã¿ãã§ã¼ã¹ã¯ããããªæãã§ãã
// ãã®ã¤ã³ã¿ãã§ã¼ã¹ããç¶æ¿ããã¯ã©ã¹ã¯ãã¹ã¦ã¨ã¯ã¹ãã¼ãããã [InheritedExport] public interface ICalc<T> { T Add(T x, T y); T Div(T x, T y); }
è²ã 試ããéãã§ã¯ãå®è£ ã¯ã©ã¹ã«Exportå±æ§ãä»ãã¦ããã¾ãããããã¤ã³ã¿ãã§ã¼ã¹ã«InheritedExportå±æ§ãä»ããå¿ è¦ãããã¾ãããã¨ããããããªã¼ãã³ã¸ã§ããªãã¯åãã¨ã¯ã¹ãã¼ãããå ´åã¯ãã¤ã³ã¿ãã§ã¼ã¹ã«InheritedExportå±æ§ãä»ãã¾ãããã
å®è£ ã¯é©å½ã«ã
// ãã®ã¨ã¯ã¹ãã¼ãã¯çºè¦ãããªãã // ãããä¸ã®ãµã³ãã«ãè¦ãéããã§ããããªãã ãã©ã»ã»ã» // [Export(typeof(ICalc<>))] public class CalcImpl<T> : ICalc<T> { public T Add(T x, T y) { return (dynamic)x + y; } public T Div(T x, T y) { return (dynamic)x / y; } }
ãã¹ããªã®ã§dynamicã使ã£ã¦ãã¾ããã¦ããã¾ãã
次ã«ã¸ã§ããªãã¯ã¤ã³ã¿ãã§ã¼ã¹ã¨å®è£ ã¯ã©ã¹ã®ãããã³ã°ãå®ç¾©ããã¯ã©ã¹ãç¨æãã¾ããGenericCatalogã«ãã®ã¯ã©ã¹ã渡ããã¨ã§åã解決ã§ããããã«ãªãããã§ãã
/// <summary> /// open genericã®å ´åãå®è£ ã¯ã©ã¹ã¨ã®ãããã³ã°ãæå®ããå¿ è¦ãããã /// </summary> [Export(typeof(IGenericContractRegistry))] public class MyGenericContractRegistry : GenericContractRegistryBase { protected override void Initialize() { Register(typeof(ICalc<>), typeof(CalcImpl<>)); } }
æºåãã§ããã®ã§ããã£ãã使ã£ã¦ã¿ã¾ãããã
[Export] class Program { [Import] public ICalc<int> CalcInt32 { get; set; } [Import] public ICalc<double> CalcDouble { get; set; } public void Run() { int x = 1, y = 2; Console.WriteLine("{0} / {1} = {2}", x, y, CalcInt32.Div(x, y)); Console.WriteLine("{0} / {1} = {2}", x, y, CalcDouble.Div(x, y)); } static void Main(string[] args) { var catalog = new TypeCatalog(typeof (Program)); var generic = new GenericCatalog(catalog, new MyGenericContractRegistry()); var container = new CompositionContainer(generic); var program = container.GetExportedValue<Program>(); program.Run(); } } /* çµæ 1 / 2 = 0 1 / 2 = 0.5 */
CodePlexã®ãã©ã¼ã©ã ãããã°ã«ãã£ããµã³ãã«ãä»ã®MefContribã ã¨åããªãã®ã§è©¦è¡é¯èª¤ã«ãªãã¾ããããå¤åããããªæãã(^^;
LinFu.DynamicProxyã®ä½¿ãæ¹ãåãããªã
MefContribã«Castle以å¤ã«ãLinFu.DynamicProxyãå«ã¾ãã¦ããã®ã§å¼ã£ã¦ã¿ãã®ã§ãããã©ãã«ã使ãæ¹ãåããã¾ããã
using LinFu.DynamicProxy; public class MyInterceptor : IInterceptor { public object Intercept(InvocationInfo info) { return info.TargetMethod.Invoke(info.Target, info.Arguments); } }
ãããããCasle.DynamicProxyã¨åã使ãæ¹ã ã¨æãã®ã§ãããå²ãè¾¼ã¿å¯¾è±¡ã§ããã¯ãã®info.Targetããããã·ã«ãªã£ã¦ãããã§ããããã§ãInvokeããã¨ã¾ããå²ãè¾¼ã¿ã¡ã½ãããå¼ã³åºããã»ã»ã»ã¹ã¿ãã¯ãªã¼ãã¼ããã¼ãLinFuã®ãµã³ãã«ãè¦ãã¨ã¤ã³ã¿ã¼ã»ãã¿ã®ã³ã³ã¹ãã©ã¯ã¿ã§å²ãè¾¼ã¿å¯¾è±¡ãªãã¸ã§ã¯ãã渡ãä¾ãå¤ããInvocationInfoã ãããæ å ±ã足ãã¦ããªãæ°ããã¾ãã
using LinFu.DynamicProxy; public class MyInterceptor : IInterceptor, IWithTarget { public object Intercept(InvocationInfo info) { // info.Targetã®ä»£ããã«Targetã使ã return info.TargetMethod.Invoke(Target, info.Arguments); } public object Target { get; set; } }
ãããªé¢¨ã«ãIWithTargetã¤ã³ã¿ãã§ã¼ã¹ãå®è£ ãã¦ãã£ã¦ãMefContribLinFu.DynamicProxyInterceptor.csã
public object Intercept(object value) { var interfaces = value.GetType().GetInterfaces(); var proxyInterface = interfaces.FirstOrDefault(); var additionalInterfaces = interfaces.Skip(1).ToArray(); // å²ãè¾¼ã¿å¯¾è±¡ãã¤ã³ã¿ã¼ã»ãã¿ã«è¨å®ãã if (interceptor is IWithTarget) (interceptor as IWithTarget).Target = value; return Generator.CreateProxy(proxyInterface, this.interceptor, additionalInterfaces); }
ã¨ããã¨åãã¾ããã
ãã ãå ¨ããã¹ãããã¦ããªãã¨ã¯æããªãã®ã§ãç§ã®ä½¿ãæ¹ãééã£ã¦ããã¨æããã§ããã©ãã»ã»ã»
MEFã§AOP
éå»ã«ä¼¼ããããªãã¨ããã£ãæ°ããã¾ãããä»åã¯MefContribã使ã£ãä¸å¿ãæ£å¼ã£ã½ãæ¹æ³ã§ã
using System; using System.Linq; using System.Reflection; using System.ComponentModel.Composition; using System.ComponentModel.Composition.Primitives; using System.ComponentModel.Composition.Hosting; using MefContrib; using MefContrib.Hosting.Interception; using MefContrib.Hosting.Interception.Castle; using MefContrib.Hosting.Interception.Configuration; using Castle.DynamicProxy; namespace MefInterceptorSample { public class MyInterceptor : IInterceptor { public void Intercept(IInvocation invocation) { Console.WriteLine("Call {0}.", invocation.Method.Name); invocation.Proceed(); Console.WriteLine("Called {0}.", invocation.Method.Name); } } public interface ICalc { int Add(int x, int y); int Sub(int x, int y); } [Export(typeof(ICalc))] public class CalcImpl : ICalc { public int Add (int x, int y) { Console.WriteLine("In Add."); return x + y; } public int Sub (int x, int y) { Console.WriteLine("In Sub."); return x - y; } } [Export] public class MainClass { [Import] public ICalc Calc {private get;set;} public void Run() { Console.WriteLine(Calc.Add(1, 2)); Console.WriteLine(Calc.Sub(1, 2)); } public static void Main (string[] args) { // å²ãè¾¼ã¿å¯¾è±¡ã¨ãªãã¯ã©ã¹ç¨ã«ã¿ãã° // å²ãè¾¼ããªãã¯ã©ã¹ãã«ã¿ãã°ã«å«ã¾ãã¦ããã¨ä¾å¤ãçºçããã®ã§ã«ã¿ãã°ãåãã(æãããã°) var targetCatalog = new TypeCatalog(typeof(CalcImpl)); // Castle DynamicProxyã使ã£ã¦å²ãè¾¼ã var interceptor = new DynamicProxyInterceptor(new MyInterceptor()); // 第2å¼æ°ã¯å²è¾¼æ¡ä»¶ãããã§ã¯ç¡æ¡ä»¶ã«å²ãè¾¼ã¾ããããã常ã«trueã var criteria = new PredicateInterceptionCriteria(interceptor, _=>true); // å²ãè¾¼ã¿ç¨ã«ã¿ãã°ã var config = new InterceptionConfiguration().AddInterceptionCriteria(criteria); var interceptCatalog = new InterceptingCatalog(targetCatalog, config); // å²ãè¾¼ã¿å¯¾è±¡å¤ã®ã¯ã©ã¹ç¨ã«ã¿ãã°ã var otherCatalog = new TypeCatalog(typeof(MainClass)); var container = new CompositionContainer(new AggregateCatalog(interceptCatalog, otherCatalog)); var main = container.GetExportedValue<MainClass>(); main.Run(); } } } /* çµæ Call Add. In Add. Called Add. 3 Call Sub. In Sub. Called Sub. -1 */
InterceptingCatalogã使ã£ãå²ãè¾¼ã¿ã§ããããããæçµçã§ã¯ãªããã¢ã¤ãã£ã¢åéä¸ã¿ãããªãã¨ãã©ããã®ãã©ã¼ã©ã ã§è¦ãæ°ããã¾ãã
ãã¨ãã³ã¡ã³ãã«ãæ¸ãã¾ããããCastle.DynamicProxyã使ã£ã¦ããå ´åãinterfaceç¶æ¿ãããã¯ãä»®æ³ã¡ã½ããã§ãªãã¨å²ãè¾¼ã¿ã§ããªãã®ã§ãããå²ãè¾¼ã¿å¯¾è±¡ãåå¨ããªãå ´åãä¾å¤ãçºçãã¦ãã¾ãã¾ããæãããã°ã ã¨ã¯æãã¾ãããåããããã«ã¿ãã°ãåãããã¨ã§åé¿å¯è½ã§ãã
ãããã§è¦ããããµã³ãã«ã³ã¼ãã§ã¯ãExportMetadataå±æ§ã使ã£ã¦å²ãè¾¼ã¿å¯¾è±¡ã®å¶å¾¡ããããªã£ã¦ãã¾ããããã«ã¹ã¿ã å±æ§ã ã¨ã½ã¼ã¹ã³ã¼ããå¿ è¦ãªä¸ãåã³ã³ãã¤ã«ãå¿ è¦ã§ããAOPèªä½å¤ç¨ãããã®ã§ã¯ããã¾ããããæ³å®ããã使ç¨ç¶æ³ãèããã¨ãããã¯ã¤ãã¤ããªæ°ããã¾ããã
JetBrains.Annotations
ReSharperã¯ã³ã¼ãåæãã¦nullåç §ãçºçããå¯è½æ§ãããã¨ãããææããæ©è½ãããã¾ãã
ãã®ããã«è©²å½ç®æã«æ³¢ç·ãåºã¦ä¾¿å©ã§ãã
ããããã¡ã½ããã®æ»ãå¤ãnullã®å ´åã¯ãæ®å¿µãªãããã§ãã¯ããã¾ããã
ãã ããã®æ©è½ã¯ã«ã¹ã¿ã å±æ§ã使ããã¦ããã®ã§ãnullãã§ãã¯ããããã¡ã½ããã«ã«ã¹ã¿ã å±æ§ãä»ãããã¨ã§å¯¾å¿å¯è½ã§ãã
ä¸è¨ã®ããã«ReSharperã®ãªãã·ã§ã³è¨å®ãããCode Annotationsã表示ãããã¨ãã«ã¹ã¿ã å±æ§ã®ããã©ã«ãå®è£
ãã¯ãªãããã¼ãã¸ã³ãã¼åºæ¥ãã®ã§ããããèªåã®ããã¸ã§ã¯ãã«åãè¾¼ã¿ã¾ãã
ããã§ReSharperå´ã§ä½¿ã£ã¦ããã«ã¹ã¿ã å±æ§ãå©ç¨ã§ããããã«ãªãã¾ãããã§ã¯ãæ©éã
CanBeNullå±æ§ãä»ãããã¨ã§ã³ã¼ãåæãnullåç
§ãæ¤åºã§ããããã«ãªãã¾ãããã
WebActivatorã¨PreApplicationStartMethodAttribute
MefContrib.MVC3ã«ãã£ã¦çæããããAppStart_MefContribMVC3.csã«ã¯ãMEFã使ç¨ããããã®åæåã³ã¼ããããã¾ããããã®ã³ã¼ãã¯èª°ãå¼ã³åºãã¦ããã®ã§ããããï¼
[assembly: WebActivator.PreApplicationStartMethod(typeof(TestMvcApplication.App_Start.AppStart_MefContribMVC3), "Start")]
ãã¡ã¤ã«ãè¦ãã¦ã¿ãã¨ä¸è¨ã®ãããªã«ã¹ã¿ã å±æ§ãè¦ã¤ããã¾ãããã®WebActivatorãã¢ã»ã³ããªã®èªã¿è¾¼ã¿æã«æå®ãããã¡ã½ãããå¼ã³åºãã¦ãããã®ã§ããã
ã¨ããã§ã.NET4ã®FCLããã§ãã¯ãã¦ãã人ãªããSystem.Web.PreApplicationStartMethodAttributeã¨åããããªãã®ï¼ã¨çåã«æãããç¥ãã¾ãããéãã確èªããããã«ä»¥ä¸ã®ã·ããªãªãèãã¦ã¿ã¾ãã
ãMEFã¨åæã«ä»ã®ãã¬ã¼ã ã¯ã¼ã¯ã使ç¨ããã
ã§ãNuGetã使ã£ã¦åç
§ã追å ããã¨ãApp_Startãã©ã«ãã¯ä»¥ä¸ã®ããã«ãªã£ãã¨ãã¾ãã
- App_Start
- AppStart_MefContribMVC.cs (MEF)
- AppStart_FooFramework.cs (ä»ã®ãã¬ã¼ã ã¯ã¼ã¯)
WebActivatorã使ããªãå ´åã¯ããã®ä¸¡æ¹ã®ãã¡ã¤ã«ã«
[assembly: PreApplicationStartMethod(typeof(AppStart_MefContribMVC), "Run")]
[assembly: PreApplicationStartMethod(typeof(AppStart_FooFramework), "Run")]
ãæå®ããããã¨ã«ãªãã¯ãã§ãã
ã»ã»ã»ããããããã«ãã¨ã©ã¼ã«ãªããã§ãããã
PreApplicationStartMethodAttributeã¯1ã¢ã»ã³ããªã«ï¼ã¤ããä»ããããªãã®(AllowMultiple=false)ã»ã»ã»
ã¶ã£ã¡ãããè¨è¨ãã¹ã§ãããã(^^; ãã¡ãããä½ã£ãå´ãããã¯èªèãã¦ãã¦ã
Light up your NuGets with startup code and WebActivator – Angle Bracket Percent
The reason is that we were short sighted when we designed this feature in ASP.NET, and only allowed this attribute to be used once per assembly.
å è¦ã®æãç¡ãã£ãã¨çç´ã«è¨ã£ã¦ãã¾ãã
ã£ã¨ãããã¨ã§ãNuGetã®ããã¸ã§ã¯ãã§ã¯PreApplicationStartMethodAttributeã®ä»£ããã«WebActivatorã使ããã¦ããã¨ãã訳ã§ããã
ASP.NET MVC 3ã§MEFã使ã
MefContrib.MVC3ã使ãã¨ç°¡åã«ASP.NET MVCããMEFã使ããã®ã§ãç´¹ä»ã
åæï¼NuGetãã¤ã³ã¹ãã¼ã«æ¸ã¿ãªãã¨ã
ã¾ããASP.NET MVC3ã®ããã¸ã§ã¯ãã®ç¨æãã¾ãããã
é¢åãªã®ã§ããã©ã«ãå®è£
ããã§ã
ã§ã¯ãMEFã使ããããã«ãã¾ããããNuGetãã¤ã³ã¹ãã¼ã«ããã¦ããã¨ãAdd Library Package Reference...ãã¡ãã¥ã¼ãé¸ã¹ã¾ãã
MefContrib.MVC3ãé¸æãã¦ã¤ã³ã¹ãã¼ã«ãã¾ãã
ããã¨ãå¿
è¦ãªã©ã¤ãã©ãªããã¦ã³ãã¼ããããåç
§ã追å ããã¾ããã¾ããASP.NET MVCããMEFã使ãããã®ãã¾ããªãã³ã¼ããããã¸ã§ã¯ãã«è¿½å ããã¾ãã
èå³ããããªããAppStart_MefContribMVC3.csãè¦ãã¦ã¿ã¦ãã ããã
ããã§ãMEFã使ããããã«ãªãã¾ãããã§ã¯ãå®éã«ä½¿ã£ã¦ã¿ã¾ãããã
ã¨ããããããLogicsããã£ã¬ã¯ããªã«ã¤ã³ã¿ãã§ã¼ã¹ãããLogics.Implãã«ãã®å®è£
ã¯ã©ã¹ãç½®ããã¨ã«ãã¾ãããã¡ãããã©ãã§ãããã§ãã
ã¤ã³ã¿ãã§ã¼ã¹ã¯ã馴æã¿ã®ãããã
namespace TestMvcApplication.Logics { public interface IGreeting { string Say(string msg); } }
ãã§ããããã¼ãªå®è£ ã
using System; using System.ComponentModel.Composition; namespace TestMvcApplication.Logics.Impl { [Export(typeof(IGreeting))] public class GreetingImpl : IGreeting { public string Say(string msg) { return String.Format("Say ã{0}ã", msg); } } }
MEFã使ã£ã¦IGreetingãã¨ã¯ã¹ãã¼ããã¦ãã¾ãã
ã§ã¯ããããHomeControllerãã使ã£ã¦ã¿ã¾ãããã
using System.ComponentModel.Composition; using System.Web.Mvc; using TestMvcApplication.Logics; namespace TestMvcApplication.Controllers { public class HomeController : Controller { [Import] public IGreeting Greeting { get; set; } public ActionResult Index() { ViewBag.Message = Greeting.Say("ASP.NET MVC ã¸ãããã"); return View(); } public ActionResult About() { return View(); } } }
IGreetingãã¤ã³ãã¼ããã¦å¼ã³åºãã ãã
MefContrib.MVC3ã使ãã¨ãããããç°¡åã«MEFãå©ç¨ã§ãã¾ããã