91
Chương 3: Miền ứng dụng, cơ chế phản chiếu, và siêu dữ liệu
// Hiện thực các thành viên ở đây.
§
}
3.
3.
Tránh n p các assembly không c n thi t vào mi n ng d ngạ ầ ế ề ứ ụ
Tránh n p các assembly không c n thi t vào mi n ng d ngạ ầ ế ề ứ ụ
#eAJwAJ>Z]tAOIQQ>cOJ>@jZLK@QVWAB‚ZcYe@B@?cJSJO@GA~ABhUABs>SJ
A>cZ‹QZ]A>@CAFeAs>TABOZKA
CLR
Aedf@CZh?Y@qZOTQRs@tZJbcLK@
QVWABD\XJSJO@GA~ABhUABQHZABB@cA(
!^ABB^@Q>cOJ>@jZLK@QVWABQHXABOIQ
System.Runtime.Remoting.ObjectHandle
D\s>@JwAQHZ]vZPQLK@QVWABQ>ls>T@d>UJYe@(
w&*'.D$marshal-by-valuegMBVh9.:)8&=@
*..D$'.:)2l'Fq&
=*(.&':>)K.4D$.:)
UF8'.IMBV9.:)@)3I&
=*(.&'4NI.:)'"S$*
%(.&'Q'@4$FV.:)I4
F.:):Gg;(..^ch
y
ObjectHandle
X&*FF.ID$'9.:
).&=4*>.(.&'wD$'I.:)
28&*F4.ID$8&=@*(.&'NI
X&*';ID$&% lFF.D$g2)
System.Data.DataSet
h8&*F=\
// Tạo một DataSet mới.
System.Data.DataSet data1 = new System.Data.DataSet();
// Cấu hình/thêm dữ liệu cho DataSet.
§
// Đóng gói DataSet.
System.Runtime.Remoting.ObjectHandle objHandle =
new System.Runtime.Remoting.ObjectHandle(data1);
l4.D$8O)M:
ObjectHandle.Unwrap
X
e$82)\
// Khôi phục DataSet từ ObjectHandle.
System.Data.DataSet data2 =
(System.Data.DataSet)objHandle.Unwrap();
92
Chương 3: Miền ứng dụng, cơ chế phản chiếu, và siêu dữ liệu
4.
4.
T o ki u không th v t qua biên mi n ng d ngạ ể ể ượ ề ứ ụ
T o ki u không th v t qua biên mi n ng d ngạ ể ể ượ ề ứ ụ
#eAJwAQeXOIQs@tZh?Y@qZfcXJ>XJSJQ>t>@qAJbcs@tZA\]s>TABQ>tLVWJ
QHZ]vZPQQƒO}YqA>‰JSJO@GA~ABhUABs>SJ(
>R@J>{JJ>{As@tZh?Y@qZQ>ZIJheAB
nonremotable
Q~JY\s>TABQ>tQZwAQn
>^cJ“ABA>Vs>TABhpAvZPQQƒYEd
MarshalByRefObject
(
l4&*.D)KFJ$*';*..:
)l*)K)*nonremotable8/5'4z
Nz=zF?4)3;g=I'IhQ
MarshalByRefObject
HK'@.&5*D$4$';Q
.:)gD$'4$O).DD'i
0M:>.:)h
l)K4zNz=zF$=)r)).
4QIvN=FQFl&..4
zNz=zF8&*//5!2
System.SerializableAttribute
4
$)&
L*NB.&.4$'&5.IH
.NET )3;=I'IQ
MarshalByRefObject
T&*x6
4)3 ;&*Q'HK MC4))3;Q
MarshalByRefObject
& t.\
System.ComponentModel.Component
8
System.IO.Stream
8
System.IO.TextReader
8
System.IO.TextWriter
8
System.NET.WebRequest
8
System.Net.
WebResponse
g;(..NET Framework SDK F)¯°¤‘¯±‘)3;Q
MarshalByRefObject
h
5.
5.
N p assembly vào mi n ng d ng hi n hànhạ ề ứ ụ ệ
N p assembly vào mi n ng d ng hi n hànhạ ề ứ ụ ệ
#eAJwAAedOIQcff†OFY]D\XO@GA~ABhUABY•JQ>nJQ>@(
g hUAB d>V[AB Q>~J Q„A>
Load
>c]
LoadFrom
Jbc YEd
System.Reflection.Assembly
(
L==*(.&'.(.&'&*.IIG&>)i7'
>8&*?FJi&=*(.&'PM:
Load
LoadFrom
=.4*.(.&'.:)8
.D$
Assembly
.4(.&'Q$*|=&K
M:)DD$6)*(.&'N*8
:&=ii(.&''
RM:
Load
)*:XJi(.&'N*8&*F
O).K)*\
•
"
string
:>N''>œ•ž–˜‘²¥°–‘¯³‘6)*(.&'
93
Chng 3: Min ng dng, c ch phn chiu, v siờu d liu
"
System.Reflection.AssemblyName
.4I(.&'
".&'(:)KÊƠ Ơ(.&'
74 8 > (.&' $ O) * (.&' 7> N' .
(.&'&t.\>8>&8ăàảê8(F48$<&C)
x' g2 )\
System.Data, Version=1.0.5000.0, Culture=neutral, PublicKeyToken=
b77a5c561934e089
h l J i . (.&' 4 F > .*8 O )
PublicKeyToken=null
L*?FO)>/6)*.(.&'2
>(.&'g4FN.Chl*.S)<'%&'
O)M:
Load
\
// Np assembly System.Data dựng tờn y .
string name1 = "System.Data,Version=1.0.5000.0," +
"Culture=neutral,PublicKeyToken=b77a5c561934e089";
Assembly a1 = Assembly.Load(name1);
// Np assembly System.Xml dựng AssemblyName.
AssemblyName name2 = new AssemblyName();
name2.Name = "System.Xml";
name2.Version = new Version(1,0,5000,0);
name2.CultureInfo = new CultureInfo("");
name2.SetPublicKeyToken(
new byte[] {0xb7,0x7a,0x5c,0x56,0x19,0x34,0xe0,0x89});
Assembly a2 = Assembly.Load(name2);
// Np assembly SomeAssembly dựng tờn ngn.
Assembly a3 = Assembly.Load("SomeAssembly");
wM:
Load
$08&==9%ii*(.&'U
<'@F./9%'T&*..NET Framework SDK&I>.
I
Z HI&*Ji(.&'>.*8M:
Load
@) version policy
g2>&hpublisher policyg2hƠãƠáạƠà
ằƠÊÔĐẳẵơơắĐƠăàêơăÔạƠĂVersionpolicy $
J i f( % .' 2 ' : ) &* &5 N O
<bindingRedirect>
Publisher policy$JiêơăÔă$
!&>GACgGlobal Assembly Cacheh
] "S;iG>&(.&'NO)8&=@D/
*(.&'>.*QGAC
^ HI(.&'4F>.*!4$%.'GAC8&=@
%. NO
<codeBase>
f( % .' 2 : ) RN O
<codeBase>
;*>(.&'.f('.URLHI(.&'F>
.*8
<codeBase>
FJI&i2URL)=z>z((TI
94
Chng 3: Min ng dng, c ch phn chiu, v siờu d liu
48
<codeBase>
JI..-ảMD.:
)HI(.&'4t*i2$Ji8M:
Load
@X.
*
System.IO.FileNotFoundException
_ HI4FNO
<codeBase>
M:(.&'8&=@%.(.&'
&56probingY%probing@%.f(N>F>(.&'g
N.Cdll'exehi2\
7.D:)
P.ãê.De$>ăàảê(.&'
ặƠâãẵêƠâầắãâẩẫƠấảƠĂ
RM:
Load
)r%.*(.&'8?FD
2)k.%.(.&'F>'IRM:
LoadFrom
X&**(.&'Q.i2;i8I4%.'F@X.
*
FileNotFoundException
L=@4D%.(.&'M:
Load
EM:
LoadFrom
4#$GAC8policy8NO
<codeBase>
'probingU
<'*.S%&'O)
LoadFrom
*c:\shared\MySharedAssembly.dlly
B58
Load
8
LoadFrom
'>N&*JiN.Cf((.&'
// Np assembly cú tờn l c:\shared\MySharedAssembly.dll
Assembly a4 = Assembly.LoadFrom(@"c:\shared\MySharedAssembly.dll");
6.
6.
Th c thi assembly mi n ng d ng khỏc
Th c thi assembly mi n ng d ng khỏc
#eAJwAQ>nJQ>@OIQcffOFY]OIQO@GA~ABhUABs>SJO@GA~ABhUAB
>@qA>\A>(
@d>V[ABQ>~J
ExecuteAssembly
JbcLK@QVWAB
AppDomain
ĂÂÊÔƠ O@GA
~ABhUABD\J>LMA>QCAJbccffOFY]JwAQ>nJQ>@(
HI&*F.(.&'z=z.D*=F..:)8
M:
ExecuteAssembly
@G&*RM:
ExecuteAssembly
F&D)*:
U*:MJ6.
string
:>(.&'N
=T&*FJi.f(&'.URL")*:X&*
Ji::gevidenceh(.&'g;(..Z^ZdhDD'I.
6(.&'gMMDD)kh
RM:
ExecuteAssembly
*(.&'$Ji=M:$i
q>)K.6(.&'g M:
Main
hHI
(.&'$Ji 4 Fv =8
ExecuteAssembly
@X.*
System.Runtime.InteropServices.COMException
L=4=(.&'
.%.8%I9'.@4I9%=
(.&'IGU
ExecuteAssembly
*.(.&'&5>ƠgJF>
f(h8CLR@4)eGAC'probing%.(.&'g;(..^`&I>.
Ih
95
Chương 3: Miền ứng dụng, cơ chế phản chiếu, và siêu dữ liệu
u2))<'%&'O)M:
ExecuteAssembly
*=.
(.&' y
ExecuteAssemblyExample
* .
AppDomain
= 2 F
AppDomain
&5 M :
ExecuteAssembly
wI 9 F &
ExecuteAssemblyExample
$*.:)
using System;
public class ExecuteAssemblyExample {
public static void Main(string[] args) {
// Nếu assembly đang thực thi trong một AppDomain
// có tên thân thiện là "NewAppDomain"
// thì không tạo AppDomain mới. Điều này sẽ
// tránh một vòng lặp vô tận tạo AppDomain.
if (AppDomain.CurrentDomain.FriendlyName != "NewAppDomain") {
// Tạo miền ứng dụng mới có tên là "NewAppDomain".
AppDomain domain = AppDomain.CreateDomain("NewAppDomain");
// Thực thi assembly này trong AppDomain mới và
// truyền mảng các đối số dòng lệnh.
domain.ExecuteAssembly("ExecuteAssemblyExample.exe",
null, args);
}
// Hiển thị các đối số dòng lệnh lên màn hình
// cùng với tên thân thiện của AppDomain.
foreach (string s in args) {
Console.WriteLine(AppDomain.CurrentDomain.FriendlyName +
" : " + s);
}
}
}
7.
7.
Th hi n hóa m t ki u trong mi n ng d ng khácể ệ ộ ể ề ứ ụ
Th hi n hóa m t ki u trong mi n ng d ng khácể ệ ộ ể ề ứ ụ
#eAJwAQ>t>@qA>^cOIQs@tZQHXABOIQO@GA~ABhUABs>SJ š›œ •O@GA~AB
hUAB>@qA>\A>(
96
Chương 3: Miền ứng dụng, cơ chế phản chiếu, và siêu dữ liệu
•@ d>V[AB Q>~J
CreateInstance
>c]
CreateInstanceFrom
Jbc LK@ QVWAB
AppDomain
žŸœ• œ¡¢•£¤¥•O@GA~ABhUABLaJ>(
uO)M:
ExecuteAssembly
gS$6.^ah4.'
FvT:):*FO).:)8/
/&*.D.9%*(.&'8*)K80
>D$&>.:)
PM:
CreateInstance
CreateInstanceFrom
>&*
tG&*.9%*D$P>&MO)
M:C)=.!i8M:'I!
>&X&*DDO)&…M:C)=
RM:
CreateInstance
*.(.&'F>;i.:)&59
%S$.4M:
Assembly.Load
.^`|F8
CreateInstance
*D$..IID$.$FF
ObjectHandle
g$ .4 . ^^h 7M = I D M :
CreateInstanceFrom
T'>8
CreateInstanceFrom
*(.&'.:)&5
9%S$.4M:
Assembly.LoadFrom
.^`
AppDomain
J“AB JZAB JPd >c@ d>V[AB Q>~J HPQ Q@qA YW@ J^ QCA Y\
CreateInstanceAndUnwrap
D\
CreateInstanceFromAndUnwrap
J>•ABfmQnLIABs>T@
d>UJQ>cOJ>@jZLjALK@QVWABL}LVWJQeXQƒLK@QVWAB
ObjectHandle
‹FeAd>R@
•dLK@QVWABQHRDGJ>XL•ABs@tZQHVEJs>@fghUAB(
HI&*O)
CreateInstance
'
CreateInstanceFrom
*D$MBV
..:)8D$@$*.I@4JID
$FU:D$MBV$9&>.:)8.I'@J
I.&D$$*=.:)&PJ&**
.MBR%.I.JID$.:)g;(.
.^]&I>.IMBVMBRh
w€6MF9B.:)O)
gcontroller classh".MBRe'&IL*S'*..:
) t * D $ . : ) ' &5 M :
CreateInstance
y=:vNI:)
.:))FP:v'F&t.\*(.&'8*
>..:)8)0)‡;F.:)8'>NOM
%g&*4=C&>.:)h
u2))<'%&'O).F>
PluginManager
wS
$*..:)8
PluginManager
X&**D$F
=)
IPlugin
8*')QzF8)z
$*
using System;
using System.Reflection;
97
Chương 3: Miền ứng dụng, cơ chế phản chiếu, và siêu dữ liệu
using System.Collections;
using System.Collections.Specialized;
// Giao diện chung cho tất cả các plug-in.
public interface IPlugin {
void Start();
void Stop();
}
// Một hiện thực đơn giản cho giao diện Iplugin
// để minh họa lớp điều khiển PluginManager.
public class SimplePlugin : IPlugin {
public void Start() {
Console.WriteLine(AppDomain.CurrentDomain.FriendlyName +
": SimplePlugin starting ");
}
public void Stop() {
98
Chương 3: Miền ứng dụng, cơ chế phản chiếu, và siêu dữ liệu
Console.WriteLine(AppDomain.CurrentDomain.FriendlyName +
": SimplePlugin stopping ");
}
}
// Lớp điều khiển, quản lý việc nạp và thao tác
// các plug-in trong miền ứng dụng của nó.
public class PluginManager : MarshalByRefObject {
// ListDictionary giữ tham chiếu đến các plug-in.
private ListDictionary plugins = new ListDictionary();
// Phương thức khởi dựng mặc định.
public PluginManager() {}
// Phương thức khởi dựng nhận danh sách các plug-in.
public PluginManager(ListDictionary pluginList) {
// Nạp các plug-in đã được chỉ định.
foreach (string plugin in pluginList.Keys) {
this.LoadPlugin((string)pluginList[plugin], plugin);
}
}
// Nạp assembly và tạo plug-in được chỉ định.
public bool LoadPlugin(string assemblyName, string pluginName) {
try {
// Nạp assembly.
Assembly assembly = Assembly.Load(assemblyName);
// Tạo plug-in mới.
IPlugin plugin =
99
Chương 3: Miền ứng dụng, cơ chế phản chiếu, và siêu dữ liệu
(IPlugin)assembly.CreateInstance(pluginName, true);
if (plugin != null) {
// Thêm plug-in mới vào ListDictionary.
plugins[pluginName] = plugin;
return true;
} else {
return false;
}
} catch {
return false;
}
}
public void StartPlugin(string plugin) {
// Lấy một plug-in từ ListDictionary và
// gọi phương thức Start.
((IPlugin)plugins[plugin]).Start();
}
100
Chương 3: Miền ứng dụng, cơ chế phản chiếu, và siêu dữ liệu
public void StopPlugin(string plugin) {
// Lấy một plug-in từ ListDictionary và
// gọi phương thức Stop.
((IPlugin)plugins[plugin]).Stop();
}
public ArrayList GetPluginList() {
// Trả về danh sách các plug-in.
return new ArrayList(plugins.Keys);
}
}
public class CreateInstanceExample {
public static void Main() {
// Tạo một miền ứng dụng mới.
AppDomain domain1 = AppDomain.CreateDomain("NewAppDomain1");
// Tạo một PluginManager trong miền ứng dụng mới
// bằng phương thức khởi dựng mặc định.
PluginManager manager1 =
(PluginManager)domain1.CreateInstanceAndUnwrap(
"CreateInstanceExample", "PluginManager");
// Nạp một plug-in mới vào NewAppDomain1.
manager1.LoadPlugin("CreateInstanceExample", "SimplePlugin");
// Chạy và dừng plug-in trong NewAppDomain1.
manager1.StartPlugin("SimplePlugin");
manager1.StopPlugin("SimplePlugin");
// Tạo một miền ứng dụng mới.
AppDomain domain2 = AppDomain.CreateDomain("NewAppDomain2");