回答編集履歴

3

最後の1行追記

2017/05/17 11:38

投稿

haru666
haru666

スコア1591

test CHANGED
@@ -223,3 +223,5 @@
223
223
 
224
224
 
225
225
  設定ファイルを書くDIコンテナは、設定ファイルを読み込んで動作を変更できるようにちょっと変えただけだ。
226
+
227
+ 設定ファイルを使う場合は、現在アプリケーションに読み込まれてる型情報をリフレクションで取得しておいて、その情報に設定ファイルから得たオプションを適用していく、という形になるだろうね。

2

文章の修正

2017/05/17 11:38

投稿

haru666
haru666

スコア1591

test CHANGED
@@ -174,7 +174,7 @@
174
174
 
175
175
  情報を収集し、展開する。
176
176
 
177
- それは別にメソッドでもいいし、一般的なDIコンテナみたいになんらかのファイルでもいい。
177
+ 収集方法は別にメソッドでもいいし、一般的なDIコンテナみたいになんらかのファイルでもいい。
178
178
 
179
179
  基本は、あるインスタンスの生成方法を集積して、再帰的に呼ぶだけ。
180
180
 
@@ -202,6 +202,8 @@
202
202
 
203
203
 
204
204
 
205
+ // ISomeClassという型には、ImplemetedClassをインスタンス化してよこせ、と指示を出す。
206
+
205
207
  container.Bind<ISomeClass>().To<ImplementedClass>();
206
208
 
207
209
 
@@ -214,7 +216,7 @@
214
216
 
215
217
  ちなみにこれはNinjectっていうC#のDIコンテナを僕が使っているのでその構造に強く影響を受けている。
216
218
 
217
- NinjectはDIコンテナだけど設定ファイルを使わない、その分プログラマーには直観的だと思う。
219
+ NinjectはDIコンテナだけど設定ファイルを使わないので、その分プログラマーには直観的だと思う。
218
220
 
219
221
  ymlだのXMLだので設定ファイルを書いてインジェクションするよりよっぽど使うのが簡単なので、発想はC#未経験でもページを見ればわかると思う。
220
222
 

1

追記

2017/05/17 11:36

投稿

haru666
haru666

スコア1591

test CHANGED
@@ -24,166 +24,200 @@
24
24
 
25
25
 
26
26
 
27
+ ```C#
28
+
29
+ // あるクラスのインジェクションに関係する情報を集める
30
+
31
+ // これは関数で支持を出しても良いし、よりよい形ではリフレクションでも良い
32
+
33
+ BindingInfo<T> Bind<T>()
34
+
35
+ {
36
+
37
+ // このコンストラクタにどんな情報があるかを事前にまとめておくためのクラスがあるとして
38
+
39
+ var info = new BindingInfo(typeof(T));
40
+
41
+
42
+
43
+ // まずは器を用意しておく
44
+
45
+ cache[typeof(type)] = info;
46
+
47
+
48
+
49
+ return info;
50
+
51
+ }
52
+
53
+
54
+
55
+ // で、実装クラスの関連情報を作成した収集クラスに集める
56
+
57
+ public class BindingInfo<T>
58
+
59
+ {
60
+
61
+ // 例えばある型と紐づける
62
+
63
+ public BindedTypeInfo To(Type type)
64
+
65
+ {
66
+
67
+ // 紐づける型が派生形であることを調べる
68
+
69
+ this.Type.IsAssignableFrom(type);
70
+
71
+
72
+
73
+ // C#だとこんな風にコンストラクタの一覧はとってこれるし
74
+
75
+ var constructors = type.GetConstructors();
76
+
77
+ foreach (var constructor in constructors)
78
+
79
+ {
80
+
81
+ // ConstructorInfoからはGetParametersとかで引数はとってこれる
82
+
83
+ this.Add(new BindingConstructorInfo(constructor));
84
+
85
+
86
+
87
+ // そもそも、ConstructorInfoは実行できる
88
+
89
+ // constructor.Invoke(/*引数はオブジェクトの配列*/);
90
+
91
+ }
92
+
93
+ }
94
+
95
+
96
+
97
+ // もしくはあるインスタンスと紐づけたり
98
+
99
+ public BindedTypeInfo ToConstant(T value)
100
+
101
+ {
102
+
103
+ // ここでは、この型情報のインスタンスが欲しい時に
104
+
105
+ // ここで受け取ったvalueを返すようにする
106
+
107
+
108
+
109
+ // で、紐づけられた関連情報を更にreturn することによって
110
+
111
+ // 細かいオプションを足せるようにしてもいいだろうね!
112
+
113
+ }
114
+
115
+ }
116
+
117
+
118
+
119
+ // DIコンテナで値を取得するときは、再帰的に生成を行っていく
120
+
121
+ public T Get<T>()
122
+
123
+ {
124
+
125
+ // ある型の情報からインスタンスを取るために必要なものを考える
126
+
127
+ var info = cache[typeof(T)];
128
+
129
+ // 例えばinfoがコンスタントならその値を返すだろうし
130
+
131
+ if (info.IsConstant)
132
+
133
+ {
134
+
135
+ return info.ConstantValue;
136
+
137
+ }
138
+
139
+ else
140
+
141
+ {
142
+
143
+ // じゃなくてインスタンスを生成しなければならないなら
144
+
145
+ // 必要なコンストラクタの引数を生成するために再帰的にGet<T>する
146
+
147
+ var constructor = info.GetConstructor();
148
+
149
+ var parameters = new List<object>();
150
+
151
+ foreach(var parameterInfo in constructor.GetParameters())
152
+
153
+ {
154
+
155
+ // Getメソッドを再帰的に呼び出せばいつか端にたどり着く
156
+
157
+ parameters.Add(this.Get(parameterInfo.ParameterType));
158
+
159
+ }
160
+
161
+
162
+
163
+ // で、生成したパラメータを使ってコンストラクタを実行する
164
+
165
+ return constructor.Invoke(parameters);
166
+
167
+ }
168
+
169
+ }
170
+
27
171
  ```
28
172
 
29
- // あるクラスのインジェクションに関係する情報を集める
30
-
31
- // これは関数で支持ても良いしよりよい形ではリフレクションでも良い
32
-
33
- BindingInfo<T> Bind<T>()
34
-
35
- {
36
-
37
- // このコンストラクにどんな情報があるかを事前にまめておくためのクラスがあるとして
38
-
39
- var info = new BindingInfo(typeof(T));
40
-
41
-
42
-
43
- // まずは器を用意しておく
44
-
45
- cache[typeof(type)] = info;
46
-
47
-
48
-
49
- return info;
50
-
51
- }
52
-
53
-
54
-
55
- // で、実装クラスの関連情報を作成した収集クラスに集める
56
-
57
- public class BindingInfo<T>
58
-
59
- {
60
-
61
- // 例えばある型と紐づける
62
-
63
- public BindedTypeInfo To(Type type)
64
-
65
- {
66
-
67
- // 紐づける型が派生形であることを調べる
68
-
69
- this.Type.IsAssignableFrom(type);
70
-
71
-
72
-
73
- // C#だとこんな風にコンストラクタの一覧はとってこれるし
74
-
75
- var constructors = type.GetConstructors();
76
-
77
- foreach (var constructor in constructors)
78
-
79
- {
80
-
81
- // ConstructorInfoからはGetParametersとかで引数はとってこれる
82
-
83
- this.Add(new BindingConstructorInfo(constructor));
84
-
85
-
86
-
87
- // そもそも、ConstructorInfoは実行できる
88
-
89
- // constructor.Invoke(/*引数はオブジェクトの配列*/);
90
-
91
- }
92
-
93
- }
94
-
95
-
96
-
97
- // もしくはあるインスタンスと紐づけたり
98
-
99
- public BindedTypeInfo ToConstant(T value)
100
-
101
- {
102
-
103
- // ここでは、この型情報のインスタンスが欲しい時に
104
-
105
- // ここで受け取ったvalueを返すようにする
106
-
107
-
108
-
109
- // で、紐づけられた関連情報を更にreturn することによって
110
-
111
- // 細かいオプションを足せるようにしてもいいだろうね!
112
-
113
- }
114
-
115
- }
116
-
117
-
118
-
119
- // DIコンテナで値を取得するときは、再帰的に生成を行っていく
120
-
121
- public T Get<T>()
122
-
123
- {
124
-
125
- // ある型の情報からインスタンスを取るために必要なものを考える
126
-
127
- var info = cache[typeof(T)];
128
-
129
- // 例えばinfoがコンスタントならその値を返すだろうし
130
-
131
- if (info.IsConstant)
132
-
133
- {
134
-
135
- return info.ConstantValue;
136
-
137
- }
138
-
139
- else
140
-
141
- {
142
-
143
- // じゃなくてインスタンスを生成しなければならないなら
144
-
145
- // 必要なコンストラクタの引数を生成するために再帰的にGet<T>する
146
-
147
- var constructor = info.GetConstructor();
148
-
149
- var parameters = new List<object>();
150
-
151
- foreach(var parameterInfo in constructor.GetParameters())
152
-
153
- {
154
-
155
- // Getメソッドを再帰的に呼び出せばいつか端にたどり着く
156
-
157
- parameters.Add(this.Get(parameterInfo.ParameterType));
158
-
159
- }
160
-
161
-
162
-
163
- // で、生成したパラメータを使ってコンストラクタを実行する
164
-
165
- return constructor.Invoke(parameters);
166
-
167
- }
168
-
169
- }
173
+
174
+
175
+ 情報収集し、展開する。
176
+
177
+ それは別にメソッドでもいいし、一般的なDIコンテナみたいになんらかのファイルでもいい。
178
+
179
+ 基本は、あるインスタンスの生成方法を集積して、再帰的に呼ぶだけ。
180
+
181
+ ンスタンス化できければ情報不足として例外を投げればいい。
182
+
183
+
184
+
185
+ 実行時の動作変更用のオプションの拡張、インスタンス化に関する情報のキャッシュで高速化だとか、まあそういう細かいのはいっぱいあるだろうと思う。
186
+
187
+
188
+
189
+ とりあえず… 既存のOSSのDIコンテナのソースを見よう!
190
+
191
+
192
+
193
+ #追記
194
+
195
+
196
+
197
+ 上のクラスの使い方の想定をかいてなかったね。
198
+
199
+ ```C#
200
+
201
+ var container = new MyDIContainer();
202
+
203
+
204
+
205
+ container.Bind<ISomeClass>().To<ImplementedClass>();
206
+
207
+
208
+
209
+ var implemented = container.Get<ISomeClass>();
170
210
 
171
211
  ```
172
212
 
173
213
 
174
214
 
175
- 情報を収集し、展開する。
176
-
177
- れは別にメソッドでもいし、一般的なDIコンテナみたになんらかファイル
215
+ ちなみにこれはNinjectってうC#のDIコンテナを僕が使ってのでその構造に強く影響を受けて
178
-
216
+
179
- 基本は、あるンスタンスの生成方法集積して再帰に呼ぶ
217
+ NinjectDIコンテナだけど設定ファ使わないその分プログラマーには直観的だと思う
180
-
181
- インスタンス化できなければ情報不足として例外を投げればいい。
218
+
182
-
183
-
184
-
185
- 実行時動作変更用オプションの拡張、インスタンス化に関する情報キャッシュ高速化だとかまあそういう細いのはいっぱいあだろうと思う。
219
+ ymlだXMLだで設定ファイルを書いてインジェクションするよりよっぽど使うが簡単なので、発想はC#未経験でもページを見ればわかると思う。
186
-
187
-
188
-
220
+
221
+
222
+
189
- とりあえず… 既存のOSSのDIコンテナのソースよう
223
+ 設定ファイルを書くDIコンテナは、設定ファイル読み込んで動作を変更できるようにちょっと変えただけだ。