【MEF】(仮)リフレクション べース プログラミング モデル。

  • 2010.05.25 Tuesday
  • 21:28
JUGEMテーマ:コンピュータ
 
正しい名前がわからないので「リフレクション べース プログラミング モデル」に(仮)をつけてみましたが、MEFには属性付きプログラミングモデルではなく、リフレクションがべースとなるプログラミングモデルも存在するはずです。たとえば、XML形式でExportやImportを指定し、そこからリフレクションでアセンブリから実際にインスタンスを管理していく方法です。

MSDNライブラリーを眺めてみると、ツール類はそろっているようです。

ReflectionModelServices クラス
リフレクション ベースのパーツを作成および取得する拡張メソッドを提供します。
名前空間:  System.ComponentModel.Composition.ReflectionModel
アセンブリ:  System.ComponentModel.Composition (System.ComponentModel.Composition.dll 内)

メンバーをみると楽しげなのがいっぱいあります。



ちなみに属性付きプログラミングモデル用に

AttributedModelServices クラス
属性付きのプログラミング モデルを合成で使用するためのヘルパー メソッドが含まれています。
名前空間:  System.ComponentModel.Composition
アセンブリ:  System.ComponentModel.Composition (System.ComponentModel.Composition.dll 内)

というのがあり、最近、よく使ってます・・・ただし、ReflectionModelServices側のメソッドを使った方がよかったような気がするサンプルコードもありますが・・・汗

【MEF】自作カタログ 絶対真似しないでください危険です。

  • 2010.05.25 Tuesday
  • 20:59
JUGEMテーマ:コンピュータ

Source and Project


※当Blogの最近のMEFの投稿はMEFフレームワークを必ずしも正しい使い方をしているとは限りませんので注意してください。

ComposablePartCatalog クラス、ComposablePartDefinition クラス、ComposablePart クラスを使用して自作カタログを作成しました。クラスのそれぞれの責務はMSDNライブラリーによると

-------------------
ComposablePartCatalog クラス
ComposablePartDefinition オブジェクトを収集して返すコンポーザブル パーツ カタログの抽象基本クラスを表します。

ComposablePartDefinition クラス
ComposablePart オブジェクトの作成を記述して有効にするコンポーザブル パーツ定義の抽象基本クラスを定義します。

ComposablePart クラス
オブジェクトをインポートしたり、エクスポートされたオブジェクトを生成したりするコンポーザブル パーツの抽象基本クラスを定義します。
--------------------

カタログを自作したり拡張したい場合にすべてをこれらの抽象クラスから直接継承する必要は全くないと思いますが、これらの抽象クラスのメンバーがいつ呼ばれるのかシーケンスが知りたいのと、属性付きプログラミング モデル以外でも実装可能なことを試してみたいなど、いろいろやってみたいことがあったので、実装してみました。

using System;
using System.Collections.Generic;
using System.ComponentModel.Composition.Primitives;
using System.Linq;

namespace Art55.MEF.JunkLib
{
    public class MyComposablePartCatalog : ComposablePartCatalog
    {
        public MyComposablePartCatalog(params Type[] types)
        {
            _partDefinitionList = new List<ComposablePartDefinition>();
            foreach (Type type in types)
            {
                _partDefinitionList.Add(new MyComposablePartDefinition(type));
            }
        }

        public override IQueryable<ComposablePartDefinition> Parts
        {
            get { return _partDefinitionList.AsQueryable(); }
        }

        private readonly List<ComposablePartDefinition> _partDefinitionList;
    }
}


using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition.Primitives;
using System.Linq;
using System.Reflection;

namespace Art55.MEF.JunkLib
{
    class MyComposablePartDefinition : ComposablePartDefinition
    {
        public MyComposablePartDefinition(Type type)
        {
            _type = type;
            var metadata = new Dictionary<string, object>();
            metadata[CompositionConstants.ExportTypeIdentityMetadataName] =
                AttributedModelServices.GetTypeIdentity(type);
            _rootExportDefinition = new ExportDefinition(AttributedModelServices.GetContractName(type), metadata);
            _exportDefinitionList = new List<ExportDefinition> { _rootExportDefinition };
            _importDefinitionList = new Dictionary<ImportDefinition, PropertyInfo>();
            foreach (PropertyInfo propertyInfo in type.GetProperties())
            {
                if (propertyInfo.CanWrite)
                {
                    Type importType = propertyInfo.PropertyType;
                    var importDefinition = new ContractBasedImportDefinition(
                        AttributedModelServices.GetContractName(importType),
                        AttributedModelServices.GetTypeIdentity(importType),
                        Enumerable.Empty<KeyValuePair<string, Type>>(),
                        ImportCardinality.ExactlyOne,
                        false,
                        false,
                        CreationPolicy.Shared);
                    _importDefinitionList.Add(importDefinition, propertyInfo);
                }
            }
        }

        public override IEnumerable<ExportDefinition> ExportDefinitions
        {
            get { return _exportDefinitionList; }
        }

        public override IEnumerable<ImportDefinition> ImportDefinitions
        {
            get { return _importDefinitionList.Keys; }
        }

        public override ComposablePart CreatePart()
        {
            return new MyComposablePart(this);
        }

        public Export CreateExport()
        {
            return new Export(_rootExportDefinition, () => Activator.CreateInstance(_type));
        }

        internal void SetImport(object obj, ImportDefinition importDefinition, Export export)
        {
            if (_importDefinitionList.ContainsKey(importDefinition))
            {
                PropertyInfo propertyInfo = _importDefinitionList[importDefinition];
                propertyInfo.SetValue(obj, export.Value, null);
            }
        }

        private readonly Type _type;
        private readonly ExportDefinition _rootExportDefinition;
        private readonly List<ExportDefinition> _exportDefinitionList;
        private readonly Dictionary<ImportDefinition, PropertyInfo> _importDefinitionList;
    }
}


using System;
using System.Collections.Generic;
using System.ComponentModel.Composition.Primitives;
using System.Linq;

namespace Art55.MEF.JunkLib
{
    class MyComposablePart : ComposablePart
    {
        public MyComposablePart(MyComposablePartDefinition definition)
        {
            if (definition == null)
                throw new ArgumentNullException("definition");

            _definition = definition;
        }

        public override IEnumerable<ExportDefinition> ExportDefinitions
        {
            get { return _definition.ExportDefinitions; }
        }

        public override IEnumerable<ImportDefinition> ImportDefinitions
        {
            get { return _definition.ImportDefinitions; }
        }

        public override object GetExportedValue(ExportDefinition definition)
        {
            if (_definition.Equals(definition))
                throw new ArgumentException("definition");

            object result = _definition.CreateExport().Value;
            foreach (ImportDefinition importDefinition in _importSetting.Keys)
            {
                if (_importSetting.ContainsKey(importDefinition) && _importSetting[importDefinition].Count() == 1)
                {
                    _definition.SetImport(result, importDefinition, _importSetting[importDefinition].First());
                }
            }
            return result;
        }

        public override void SetImport(ImportDefinition definition, IEnumerable<Export> exports)
        {
            _importSetting[definition] = exports;
        }

        private readonly Dictionary<ImportDefinition, IEnumerable<Export>> _importSetting = new Dictionary<ImportDefinition, IEnumerable<Export>>();
        private readonly MyComposablePartDefinition _definition;
    }
}

これらのクラスを使用してカタログを作成すると

指定したTypeは必ずExportとなり、publicなGetterが存在するプロパティは必ずImportとして設定されます。そして、Exportからインスタンスを作成時にインジェクションされます。実際のライブラリーを使用してインスタンスを作成するコードを書いてみると

using System;
using System.ComponentModel.Composition.Hosting;
using Art55.MEF.JunkLib;

namespace Art55.MEFSample20100525_001
{
    class Program
    {
        static void Main(string[] args)
        {
            var types = new[] {typeof (B), typeof (A), typeof (C)};
            var catalog = new MyComposablePartCatalog(types);
            var container = new CompositionContainer(catalog);
            A a = container.GetExportedValue<A>();
            a.Say();
        }
    }

    public class A
    {
        public B BObject { private get; set; }
        public void Say()
        {
            BObject.Say();
        }
    }

    public class B
    {
        public C CObject { private get; set; }
        public void Say()
        {
            CObject.Say();
        }
    }

    public class C
    {
        public void Say()
        {
            Console.WriteLine("C Say");
        }
    }
}

実行すると

C Say

と出力されます。一応、属性指定なしにExportやImportが指定可能なカタログが作成できました。

Source and Project

【MEF】ImportDefinition.IsConstraintSatisfiedBy メソッド

  • 2010.05.24 Monday
  • 21:35
JUGEMテーマ:コンピュータ
 ImportDefinition.IsConstraintSatisfiedBy メソッド
指定した定義で表されるエクスポートが、このインポート定義の制約を満たすかどうかを示す値を取得します。

これがうまくいかない!





・・・独り言です。

【MEF】ContractBasedImportDefinition クラス

  • 2010.05.22 Saturday
  • 23:50
JUGEMテーマ:コンピュータ

http://mef.codeplex.com/wikipage?title=FAQ&referringTitle=Guide
CodePlexの上記のページを眺めていたらContractBasedImportDefinitionの引数が微妙に違うことに気づき、.NET Framework 4のMEFはどう書くんだろうか気になったのでためしにコードを書いてみました。

using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition.Primitives;
using System.Linq;
using System.Text;

namespace Art55.MEFSample20100522_001
{
    class Program
    {
        static void Main(string[] args)
        {
            var catalog = new TypeCatalog(new[] { typeof(A), typeof(B) });
            var container = new CompositionContainer(catalog);
            var importDefinition = new ContractBasedImportDefinition(
                AttributedModelServices.GetContractName(typeof(A)),
                AttributedModelServices.GetTypeIdentity(typeof(A)),
                Enumerable.Empty<KeyValuePair<string, Type>>(),
                ImportCardinality.ExactlyOne,
                false,
                false,
                CreationPolicy.Shared);
            Export export = container.GetExports(importDefinition).First();
            A a = (A) export.Value;
            a.Say();
        }
    }

    [Export]
    class A
    {
        [Import]
        public B BObject { private get; set; }
        public void Say()
        {
            BObject.Say();
        }
    }

    [Export]
    class B
    {
        public void Say()
        {
            Console.WriteLine("B Say.");
        }
    }
}

実行すると

B Say.

とまあいつものとおり動きました。

ExportProvider.GetExports メソッド (ImportDefinition)は指定したインポート定義の条件に一致するすべてのエクスポートを取得します。との事なので属性付きプログラミングモデル以外で自作でExportProviderを自作したい場合に何らかの方法でImportが指定されたプロパティなどからImportDefinitionを作成して、GetExports メソッドを呼び出せばいいかなーなんて・・・・たぶん。

【MEF】カラログを自作するにはどうすればいいんだ?

  • 2010.05.21 Friday
  • 22:22
JUGEMテーマ:コンピュータ


     public class MyComposablePart : ComposablePart
    {
        public override IEnumerable<ExportDefinition> ExportDefinitions
        {
            get { throw new NotImplementedException(); }
        }

        public override IEnumerable<ImportDefinition> ImportDefinitions
        {
            get { throw new NotImplementedException(); }
        }

        public override object GetExportedValue(ExportDefinition definition)
        {
            throw new NotImplementedException();
        }

        public override void SetImport(ImportDefinition definition, IEnumerable<Export> exports)
        {
            throw new NotImplementedException();
        }
    }

    public class MyComposablePartDefinition : ComposablePartDefinition
    {
        public override IEnumerable<ExportDefinition> ExportDefinitions
        {
            get { throw new NotImplementedException(); }
        }

        public override IEnumerable<ImportDefinition> ImportDefinitions
        {
            get { throw new NotImplementedException(); }
        }

        public override ComposablePart CreatePart()
        {
            throw new NotImplementedException();
        }
    }

    public class MyComposablePartCatalog : ComposablePartCatalog
    {
        public override IQueryable<ComposablePartDefinition> Parts
        {
            get { throw new NotImplementedException(); }
        }
    }

とりあえず未実装ですが、抽象クラスを並べてみました。仕様を決めてカタログを自作できそう?これでは不十分?

抽象クラスのみを使用してカタログを自作するのは難しすぎますね。既存のカタログを拡張する程度がいいのかな?

【MEF】AggregateExportProviderを使ってみた。

  • 2010.05.21 Friday
  • 01:15
JUGEMテーマ:コンピュータ

AggregateExportProvider クラス
ExportProvider
オブジェクトのコレクションによって提供されるエクスポートを集約します。

名前空間:  System.ComponentModel.Composition.Hosting
アセンブリ:  System.ComponentModel.Composition (System.ComponentModel.Composition.dll 内)


AggregateExportProviderクラスを使ってみました。


using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
namespace MEFSample
{
    class Program
    {
        static void Main(string[] args)
        {
            var catalog = new AggregateCatalog(new TypeCatalog(typeof(A), typeof(B), typeof(C)));
            var provider = new AggregateExportProvider(new CatalogExportProvider(catalog));
            var container = new CompositionContainer(catalog, provider);
            IA a = container.GetExportedValue<IA>();
            a.Say();
        }
    }
    public interface IA
    {
        void Say();
    }
    public interface IB
    {
        void Say();
    }
    public interface IC
    {
        void Say();
    }
    [Export(typeof(IA))]
    class A : IA
    {
        [Import]
        public IB B { get; set; }
        public void Say()
        {
            B.Say();
        }
    }
    [Export(typeof(IB))]
    class B : IB
    {
        [Import]
        public IC C { get; set; }
        public void Say()
        {
            C.Say();
        }
    }
    [Export(typeof(IC))]
    class C : IC
    {
        public void Say()
        {
            Console.WriteLine("C Say");
        }
    }
}

カタログ、プロバイダー(コンテナ)、エックスポート、インポート・・・いろいろ覚えることありますね。

【MEF】ComposablePartExportProviderを試してみた。

  • 2010.05.21 Friday
  • 00:30
JUGEMテーマ:コンピュータ

ComposablePartExportProviderクラス
ComposablePart
によって提供される Export オブジェクトへのアクセスを提供します。

名前空間:  System.ComponentModel.Composition.Hosting
アセンブリ:  System.ComponentModel.Composition (System.ComponentModel.Composition.dll 内)

今度はComposablePartExportProviderを使用してみました。MEFの正しい使い方をしているとは思えませんが、ちょびちょびコードを書いてみて動きを見てみたいのです。いや、MSDNライブラリーを読むのに疲れてコードが書きたくなっただけなのですが・・・

using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition.Primitives;

namespace MEFSample
{
    class Program
    {
        static void Main(string[] args)
        {
            var provider = new ComposablePartExportProvider
                               {
                                   SourceProvider =
                                       new CompositionContainer(new TypeCatalog(new[] {typeof (B)}))
                               };
            var batch =new CompositionBatch();
            batch.AddPart(new A());
            provider.Compose(batch);
            IA a = provider.GetExportedValue<IA>();
            a.Say();
        }
    }

    public interface IA
    {
        void Say();
    }

    public interface IB
    {
        void Say();
    }

    [Export(typeof(IA))]
    class A : IA
    {
        [Import]
        public IB B { get; set; }

        public void Say()
        {
            B.Say();
        }
    }

    [Export(typeof(IB))]
    class B : IB
    {
        public void Say()
        {
            Console.WriteLine("B Say");
        }
    }
}

あらかじめカタログ経由で用意していたパーツと属性によりパーツとして指定してあるオブジェクトを外部からプロバイダーに入れてみると、あらあら不思議、Import属性が指定された部分にインジェクションされている。というサンプルです。

ちょっと感動。

【MEF】CatalogExportProvider使ってみる。

  • 2010.05.20 Thursday
  • 23:12
JUGEMテーマ:コンピュータ

ExportProviderを継承するクラスがいっぱいあるみたいですが、そのひとつを使ってみました。

CatalogExportProviderクラス
指定したカタログで宣言されたすべての Export オブジェクトへのアクセスを提供します。

名前空間:  System.ComponentModel.Composition.Hosting
アセンブリ:  System.ComponentModel.Composition (System.ComponentModel.Composition.dll 内)

SourceProvider プロパティに何もいれずに実行したら、ちゃんと入れろって例外がとんできました。とても親切で感動しますね。

using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
namespace MEFSample
{
    class Program
    {
        static void Main(string[] args)
        {
            var catalogExportProvider = new CatalogExportProvider(new TypeCatalog(new [] { typeof(A) }))
                                            {
                                                SourceProvider =
                                                    new CompositionContainer(new TypeCatalog(new[] {typeof (B)}))
                                            };
            IA a = catalogExportProvider.GetExportedValue<IA>();
            a.Say();
        }
    }
    public interface IA
    {
        void Say();
    }
    public interface IB
    {
        void Say();
    }
    [Export(typeof(IA))]
    class A : IA
    {
        [Import]
        public IB B { get; set; }
        public void Say()
        {
            B.Say();
        }
    }
    [Export(typeof(IB))]
    class B : IB
    {
        public void Say()
        {
            Console.WriteLine("B Say");
        }
    }
}

CatalogExportProviderオブジェクトとCompositionContainerオブジェクトで別々に指定したパーツがめでたく合成されました。

実行結果は
-------------------
B Say




上記を下記のようにAとBをひっくり返すと合成に失敗します。


    class Program
    {
        static void Main(string[] args)
        {
            var catalogExportProvider = new CatalogExportProvider(new TypeCatalog(new [] { typeof(B) }))
                                            {
                                                SourceProvider =
                                                    new CompositionContainer(new TypeCatalog(new[] {typeof (A)}))
                                            };
            IA a = catalogExportProvider.GetExportedValue<IA>();
            a.Say();
        }
    }

System.ComponentModel.Composition.ImportCardinalityMismatchException はハンドルされませんでした。
  Message=制約 '((exportDefinition.ContractName == "MEFSample.IA") AndAlso (exportDefinition.Metadata.ContainsKey("ExportTypeIdentity") AndAlso "MEFSample.IA".Equals(exportDefinition.Metadata.get_Item("ExportTypeIdentity"))))' に一致する有効なエクスポートが見つかりませんでした。無効なエクスポートが拒否されている可能性があります。
  Source=System.ComponentModel.Composition
  StackTrace:
       場所 System.ComponentModel.Composition.Hosting.ExportProvider.GetExports(ImportDefinition definition, AtomicComposition atomicComposition)
       場所 System.ComponentModel.Composition.Hosting.ExportProvider.GetExportsCore(Type type, Type metadataViewType, String contractName, ImportCardinality cardinality)
       場所 System.ComponentModel.Composition.Hosting.ExportProvider.GetExportedValueCore[T](String contractName, ImportCardinality cardinality)
       場所 System.ComponentModel.Composition.Hosting.ExportProvider.GetExportedValue[T](String contractName)
       場所 System.ComponentModel.Composition.Hosting.ExportProvider.GetExportedValue[T]()
       場所 MEFSample.Program.Main(String[] args) 場所 c:¥users¥art55¥documents¥visual studio 2010¥Projects¥MEFSample¥MEFSample¥Program.cs:行 17
       場所 System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
       場所 System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
       場所 Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
       場所 System.Threading.ThreadHelper.ThreadStart_Context(Object state)
       場所 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean ignoreSyncCtx)
       場所 System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
       場所 System.Threading.ThreadHelper.ThreadStart()
  InnerException:

まあこんな使い方はしないですね・・・。たぶん。


----
追記)

    class Program
    {
        static void Main(string[] args)
        {
            var catalogExportProvider = new CatalogExportProvider(new TypeCatalog(new Type[0]))
                                            {
                                                SourceProvider =
                                                    new CompositionContainer(new TypeCatalog(new[] { typeof(A), typeof (B)}))
                                            };
            IA a = catalogExportProvider.GetExportedValue<IA>();
            a.Say();
        }
    }

これもダメでした・・・・うん??

【MEF】Exportクラスを使ってみる。

  • 2010.05.20 Thursday
  • 21:13
JUGEMテーマ:コンピュータ

Exportクラス

エクスポートを表します。これは、遅延作成されるエクスポート オブジェクトと、そのオブジェクトを記述するメタデータで構成される型です。

名前空間:  System.ComponentModel.Composition.Primitives
アセンブリ:  System.ComponentModel.Composition (System.ComponentModel.Composition.dll 内)

属性付きプログラミングモデルではExport属性で指定されたパーツを格納するオブジェクトがExportオブジェクトにあたると思うのですが、とりあえず使ってみました。

using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Primitives;

namespace MEFSample
{
    class Program
    {
        static void Main(string[] args)
        {
            var export = new Export(AttributedModelServices.GetContractName(typeof(A)), () => new A("A Say."));
            ExportDefinition definition = export.Definition;
            Console.WriteLine("コントラクタ名: " + definition.ContractName);
            var a = export.Value as A;
            if (a != null)
                a.Say();
        }
    }

    class A
    {
        public A(string msg)
        {
            _msg = msg ?? string.Empty;
        }

        public void Say()
        {
            Console.WriteLine(_msg);
        }

        private readonly string _msg;
    }
}

------------
実行結果

コントラクタ名: MEFSample.A
A Say.

【MEF】ExportProviderって何だろう??

  • 2010.05.20 Thursday
  • 20:26


Source and Project

先日から何度も下記のクラスを使用しました。

System.ComponentModel.Composition.Hosting.CompositionContainer

ExportやImportのパーツを合成してインスタンスを管理してくれるクラスです。ぶっちゃけどういう役割なのかよくわからず使っていたので、調べてみようと思いまして、まずはCompositionContainerクラスが継承しているExportProvider クラス(抽象クラス)を見てみることにしてみました。ベースクラスのほうがシンプルかなって単に思っただけです。

ExportProvider クラス
Lazy<T> オブジェクトを取得するためのメソッドを提供する、エクスポート プロバイダーの抽象基本クラスを定義します。

名前空間:  System.ComponentModel.Composition.Hosting
アセンブリ:  System.ComponentModel.Composition (System.ComponentModel.Composition.dll 内)

Lazy<T>オブジェクトを取得するメソッドってGetExportのことですよね?とりあえずExportProviderを継承するクラスを自作してみました。

    class MyExportProvider : ExportProvider
    {
        public MyExportProvider(Export export)
        {
            _export = export;
        }

        protected override IEnumerable<Export> GetExportsCore(ImportDefinition definition, AtomicComposition atomicComposition)
        {
            return new[] {_export};
        }

        private readonly Export _export;
    }

かなり強引ですが、外部からExportオブジェクトを渡して管理します。

実際に使ってみました。

using System;
using System.Collections.Generic;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.ComponentModel.Composition.Primitives;

namespace MEFSample
{
    class Program
    {
        static void Main(string[] args)
        {
            var provider = new MyExportProvider(new Export(AttributedModelServices.GetContractName(typeof (A)), () => new A("A Say")));
            Lazy<A> lazy = provider.GetExport<A>();
            lazy.Value.Say();
        }
    }
   
    class MyExportProvider : ExportProvider
    {
        public MyExportProvider(Export export)
        {
            _export = export;
        }

        protected override IEnumerable<Export> GetExportsCore(ImportDefinition definition, AtomicComposition atomicComposition)
        {
            return new[] {_export};
        }

        private readonly Export _export;
    }

    class A
    {
        public A(string msg)
        {
            _msg = msg ?? string.Empty;
        }

        public void Say()
        {
            Console.WriteLine(_msg);
        }

        private string _msg;
    }
}

これを実行してみると...

A Say


Lazy<A>オブジェクトが取得できたことがわかります。すんません・・・ただ試してみただけです。最近迷走中(笑)

Source and Project

calendar

S M T W T F S
     12
3456789
10111213141516
17181920212223
24252627282930
31      
<< March 2024 >>

あわせて読みたい

あわせて読みたいブログパーツ

selected entries

categories

archives

recent comment

  • 【WPF】DataGridに編集可能なComboBoxを表示するには?
    art55 (07/16)
  • 【WPF】DataGridに編集可能なComboBoxを表示するには?
    arisa (07/16)
  • 【キーボード】6年前のRealForceを復活させることはできる!?その3
    art55 (05/22)
  • 【キーボード】6年前のRealForceを復活させることはできる!?その3
    分解大好き (05/18)
  • 【.NET Framework 4.5】 IListがIReadOnlyListを継承してない理由。
    art55 (02/04)
  • 【.NET Framework 4.5】 IListがIReadOnlyListを継承してない理由。
    Gen (02/04)
  • 【キーボード】RealForce が壊れて帰ってきた。
    art55 (04/29)
  • 【.NET Framework 4.5】 IListがIReadOnlyListを継承してない理由。
    art55 (02/23)
  • 【.NET Framework 4.5】 IListがIReadOnlyListを継承してない理由。
    かるあ (02/22)
  • 【C#】Dictionaryの実装・データ構造・アルゴリズムを観察する。
    art55 (01/16)

recent trackback

recommend

recommend

recommend

C#プログラマのための.NETアプリケーション最適化技法 (Programmer's SELECTION)
C#プログラマのための.NETアプリケーション最適化技法 (Programmer's SELECTION) (JUGEMレビュー »)
Sasha Goldshtein,Dima Zurbalev,Ido Flatow,サシャ・ゴルドシュタイン,ディマ・ズルバレフ,イド・フラトー

recommend

ろんりと集合
ろんりと集合 (JUGEMレビュー »)
中内 伸光
とてもわかりやすいです。

recommend

recommend

シャノン・ノイマン・ディジタル世界
シャノン・ノイマン・ディジタル世界 (JUGEMレビュー »)
市川 忠男
4章がリレーショナルデータベースな内容になってます。ページ数があまりありませんが、ポイントがものすごく的確にまとまっていて、感動します。

recommend

recommend

東プレ Realforce91UBK-S 静音キーボード 静電容量無接点方式 変荷重 ブラック NG01BS
東プレ Realforce91UBK-S 静音キーボード 静電容量無接点方式 変荷重 ブラック NG01BS (JUGEMレビュー »)

テンキーレス、静音のRealForce91UBK-S。スコスコ感がたまらなく気持ちいいです。家と会社で2台持ってます。

recommend

recommend

プログラミング.NET Framework 第4版 (プログラミングシリーズ)
プログラミング.NET Framework 第4版 (プログラミングシリーズ) (JUGEMレビュー »)
Jeffrey Richter
発売予定美 2013年10月10日。.NET Frameworkとお付き合いする人のバイブルですね。

recommend

recommend

キャット・シッターの君に。
キャット・シッターの君に。 (JUGEMレビュー »)
喜多嶋 隆
私のイラストレータデビュー本です。

recommend

Essential .NET ― 共通言語ランタイムの本質
Essential .NET ― 共通言語ランタイムの本質 (JUGEMレビュー »)
ドン・ボックス,クリス・セルズ,Don Box,Chris Sells,吉松 史彰

links

profile

search this site.

others

mobile

qrcode

powered

無料ブログ作成サービス JUGEM