Tải bản đầy đủ (.pdf) (7 trang)

Miền ứng dụng ,cơ chế phản chiếu và siêu dữ liệu phần 1

Bạn đang xem bản rút gọn của tài liệu. Xem và tải ngay bản đầy đủ của tài liệu tại đây (192.17 KB, 7 trang )

Chương 3 : Miền ứng dụng ,cơ chế phản chiếu và siêu dữ liệu

Sức mạnh và tính linh hoạt của Microsoft .NET Framework được nâng cao bởi khả năng
kiểm tra và thao tác các kiểu và siêu dữ liệu lúc thực thi. Các mục trong chương này sẽ
trình bày các khía cạnh thông dụng của miền ứng dụng (application domain), cơ chế
phản chiếu (reflection), và siêu dữ liệu (metadata), bao gồm:

Tạo và hủy các miền ứng dụng (mục 3.1 và 3.9).

Làm việc với các kiểu và các đối tượng khi sử dụng nhiều miền ứng dụng (mục 3.2,
3.3, 3.4, và 3.8).

Làm việc với thông tin Type (mục 3.10 và 3.11).

Tạo động các đối tượng và nạp động các assembly lúc thực thi (mục 3.5, 3.6, 3.7, và
3.12).

Tạo và kiểm tra các đặc tính tùy biến (các mục 3.13 và 3.14).
1.1
Tạo miền ứng dụng
V
V


Bạn cần tạo một miền ứng dụng mới.
#
#


Sử dụng phương thức tĩnh CreateDomain của lớp System.AppDomain.
Dạng thức đơn giản nhất của phương thức CreateDomain nhận một đối số kiểu string chỉ


định tên thân thiện cho miền ứng dụng mới. Các dạng thức khác cho phép bạn chỉ định
chứng cứ (evidence) và các thiết lập cấu hình cho miền ứng dụng mới. Chứng cứ được
chỉ định bằng đố
i tượng System.Security.Policy.Evidence; mục 13.11 trình bày các tác
động của chứng cứ khi bạn tạo một miền ứng dụng. Các thiết lập cấu hình được chỉ định
bằng đối tượng System.AppDomainSetup.
Lớp AppDomainSetup chứa các thông tin cấu hình cho một miền ứng dụng. Bảng 3.1
kiệt kê các thuộc tính thường được sử dụng nhất của lớp AppDomainSetup khi tạo các
miền ứng dụng. Các thuộc tính này có thể được truy xuất sau khi tạo thông qua các thành
viên củ
a đối tượng AppDomain, và một số có thể thay đổi lúc thực thi; bạn hãy tham
khảo tài liệu .NET Framework SDK về lớp AppDomain để hiểu chi tiết hơn.

Bảng 3.1 Các thuộc tính thông dụng của lớp AppDomainSetup
Thuộc tính Mô tả
ApplicationBase
Thư mục mà CRL sẽ xét trong quá trình dò tìm
các assembly riêng. Kỹ thuật dò tìm (probing) sẽ
được thảo luận trong mục 3.5. Thực tế,
ApplicationBase là thư mục gốc cho ứng dụng
đang thực thi. Theo mặc định, đây là thư mục
chứa assembly. Có thể đọc được thuộc tính này
sau khi tạo miền ứng dụng bằng thuộc tính
AppDomain.BaseDirectory.
ConfigurationFile
Tên của file cấu hình, được sử dụng bởi mã đã
được nạp vào miền ứng dụng. Có thể đọc được
thuộc tính này sau khi tạo miền ứng dụng bằng
phương thức AppDomain.GetData với khóa
APP_CONFIG_FILE.

DisallowPublisherPolicy
Quy định phần publisher policy của file cấu hình
ứng dụng có được xét đến hay không khi xác
định phiên bản của một assembly tên mạnh để
nối kết. Publisher policy sẽ được thảo luận trong
mục 3.5.
PrivateBinPath
Danh sách các thư mục cách nhau bởi dấu chấm
phẩy mà bộ thực thi sẽ sử dụng khi dò tìm các
assembly riêng. Các thư mục này có vị trí tương
đối so với thư mục được chỉ định trong
ApplicationBase. Có thể đọc được thuộc tính này
sau khi tạo miền ứng dụng bằng thuộc tính
AppDomain.RelativeSearchPath. Có thể thay đổi
thuộc tính này lúc thực thi bằng phương thức
AppendPrivatePath và ClearPrivatePath.

Ví dụ dưới đây trình bày cách tạo và cấu hình một miền ứng dụng:
// Khởi tạo một đối tượng của lớp AppDomainSetup.
AppDomainSetup setupInfo = new AppDomainSetup();

// Cấu hình các thông tin cài đặt cho miền ứng dụng.
setupInfo.ApplicationBase = @"C:\MyRootDirectory";
setupInfo.ConfigurationFile = "MyApp.config";
setupInfo.PrivateBinPath = "bin;plugins;external";

// Tạo một miền ứng dụng mới (truyền null làm đối số chứng cứ).
// Nhớ lưu một tham chiếu đến AppDomain mới vì nó
// không thể được thu lấy theo bất kỳ cách nào khác.
AppDomain newDomain = AppDomain.CreateDomain(

"My New AppDomain",
new System.Security.Policy.Evidence(),
setupInfo);
Í
Bạn phải duy trì một tham chiếu đến đối tượng AppDomain vừa tạo bởi vì
không có cơ chế nào để liệt kê các miền ứng dụng hiện có từ bên trong mã
được-quản-lý.
1.2
Chuyển các đối tượng qua lại các miền ứng dụng
V
V


Bạn cần chuyển các đối tượng qua lại giữa các miền ứng dụng như các đối số
hay các giá trị trả về.
#
#


Sử dụng các đối tượng marshal-by-value hay marshal-by-reference.
Hệ thống .NET Remoting (sẽ được thảo luận trong chương 12) giúp việc gởi các đối
tượng qua lại các miền ứng dụng trở nên dễ dàng. Tuy nhiên, nếu bạn chưa quen với
.NET Remoting, kết quả có thể rất khác so với mong đợi. Thực ra, vấn đề gây khó khăn
khi dùng nhiều miền ứng dụng là sự tương tác với .NET Remoting và cách th
ức luân
chuyển đối tượng qua các miền ứng dụng.
Tất cả các kiểu dữ liệu có thể chia thành ba loại: nonremotable, marshal-by-value (MBV),
và marshal-by-reference (MBR). Kiểu nonremotable không thể vượt qua biên miền ứng
dụng và không thể dùng làm các đối số hay các giá trị trả về của các lời gọi trong môi
trường liên miền ứng dụng. Kiểu nonremotable sẽ được thảo luận trong mục 3.4.

Kiểu MBV
là kiểu khả-tuần-tự-hóa. Khi một đối tượng kiểu MBV được chuyển qua một
miền ứng dụng khác như là đối số hay giá trị trả về, hệ thống .NET Remoting sẽ tuần tự
hóa trạng thái hiện tại của đối tượng, chuyển dữ liệu đó sang miền ứng dụng đích, và tạo
một bản sao của đối tượng với cùng trạ
ng thái như đối tượng gốc. Kết quả là tồn tại bản
sao của đối tượng ở cả hai miền ứng dụng. Hai đối tượng này ban đầu giống nhau hoàn
toàn, nhưng độc lập nhau, nên việc thay đổi đối tượng này không ảnh hưởng đến đối
tượng kia. Dưới đây là ví dụ một kiểu khả-tuần-tự-hóa có tên là Employee, được chuyển
qua một miền ứng dụng khác bằng tr
ị (xem mục 16.1 để biết cách tạo kiểu khả-tuần-tự-
hóa).
[System.Serializable]
public class Employee {

// Hiện thực các thành viên ở đây.
§
}
Kiểu MBR là lớp dẫn xuất từ lớp System.MarshalByRefObject. Khi một đối tượng kiểu
MBR được chuyển qua một miền ứng dụng khác như đối số hay giá trị trả về, hệ thống
.NET Remoting sẽ tạo một đối tượng proxy cho đối tượng MBV cần chuyển trong miền
ứng dụng đích. Đối tượng đại diện thực hiện các hành vi hoàn toàn giống với đối t
ượng
MBR mà nó đại diện. Thực ra, khi thực hiện một hành vi trên đối tượng đại diện, hệ thống
.NET Remoting thực hiện ngầm việc chuyển lời gọi và các đối số cần thiết đến miền ứng
dụng nguồn, và tại đó thực hiện lời gọi hàm trên đối tượng MBR gốc. Kết quả được trả về
thông qua đối tượng đại di
ện. Dưới đây là một phiên bản khác của lớp Employee, được
chuyển qua một miền ứng dụng khác bằng tham chiếu thay vì bằng trị (xem mục 12.7 để
biết chi tiết về cách tạo kiểu MBR).

public class Employee : System.MarshalByRefObject {

// Hiện thực các thành viên ở đây.
§
}
1.3
Tránh nạp các assembly không cần thiết vào miền ứng dụng
V
V


Bạn cần chuyển một tham chiếu đối tượng qua lại giữa các miền ứng dụng
khác nhau; tuy nhiên, bạn không muốn CLR nạp siêu dữ liệu mô tả kiểu của
đối tượng vào các miền ứng dụng trung gian.
#
#


Đóng gói tham chiếu đối tượng trong một
System.Runtime.Remoting.ObjectHandle và khi cần truy xuất đối tượng thì
khôi phục lại.
Khi bạn truyền một đối tượng marshal-by-value (MBV) qua các miền ứng dụng, bộ thực
thi sẽ tạo một thể hiện mới của đối tượng này trong miền ứng dụng đích. Điều này có
nghĩa là bộ thực thi phải nạp assembly chứa siêu dữ liệu mô tả kiể
u của đối tượng vào các
miền ứng dụng. Do đó, việc truyền các tham chiếu MBV qua các miền ứng dụng trung
gian sẽ dẫn đến việc bộ thực thi nạp các assembly không cần thiết vào các miền ứng dụng
này. Một khi đã được nạp thì các assembly thừa này sẽ không được giải phóng khỏi miền
ứng dụng nếu không giải phóng cả miền ứng dụng chứa chúng (xem mục 3.9).
Lớp ObjectHandle cho phép bạn

đóng gói tham chiếu đối tượng để truyền qua các miền
ứng dụng mà bộ thực thi không phải nạp thêm assembly. Khi đối tượng này đến miền
ứng dụng đích, bạn có thể khôi phục tham chiếu đối tượng, bộ thực thi sẽ nạp các
assembly cần thiết và cho phép bạn truy xuất đến đối tượng như bình thường. Để đóng
gói một đối tượng (ví dụ System.Data.DataSet), bạn có thể thực hiện như
sau:
// 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);
Để khôi phục một đối tượng, sử dụng phương thức ObjectHandle.Unwrap và ép kiểu trả
về cho phù hợp, ví dụ:
// Khôi phục DataSet từ ObjectHandle.
System.Data.DataSet data2 =
(System.Data.DataSet)objHandle.Unwrap();
1.4
Tạo kiểu không thể vượt qua biên miền ứng dụng
V
V


Bạn cần tạo một kiểu dữ liệu sao cho các thể hiện của kiểu này không thể được
truy xuất từ mã lệnh ở các miền ứng dụng khác.
#
#



Phải chắc chắn kiểu dữ liệu thuộc dạng nonremotable, tức là không thể tuần tự
hóa cũng như không dẫn xuất từ lớp MarshalByRefObject.
Đôi khi bạn muốn kiểu dữ liệu nào đó chỉ được giới hạn truy xuất trong phạm vi của
miền ứng dụng. Để tạo kiểu dữ liệu dạng nonremotable, phải chắc rằng kiểu này không
phải là khả
-tuần-tự-hóa và cũng không dẫn xuất (trực tiếp hay gián tiếp) từ lớp
MarshalByRefObject. Những điều kiện này sẽ đảm bảo rằng trạng thái của đối tượng
không thể được truy xuất từ các miền ứng dụng khác (các đối tượng này không thể được
sử dụng làm đối số hay giá trị trả về trong các lời gọi phương thức liên miền ứng dụng).
Điề
u kiện kiểu dữ liệu không phải là khả-tuần-tự-hóa được thực hiện dễ dàng do một lớp
không thừa kế khả năng tuần tự hóa từ lớp cha của nó. Để bảo đảm một kiểu không phải
là khả-tuần-tự-hóa, bạn phải chắc chắn rằng đặc tính System.SerializableAttribute không
được áp dụng khi khai báo kiểu.
Bạn cần lưu ý khi đảm bảo một lớp không đượ
c truyền bằng tham chiếu. Nhiều lớp trong
thư viện lớp .NET dẫn xuất trực tiếp hay gián tiếp từ MarshalByRefObject; bạn phải cẩn
thận không dẫn xuất lớp của bạn từ các lớp này. Những lớp cơ sở thông dụng dẫn xuất từ
MarshalByRefObject bao gồm: System.ComponentModel.Component,
System.IO.Stream, System.IO.TextReader, System.IO.TextWriter,
System.NET.WebRequest, và System.Net. WebResponse (xem tài liệu .NET Framework
SDK để có danh sách đầy đủ các lớp dẫn xuất từ MarshalByRefObject).
1.5
Nạp assembly vào miền ứng dụng hiện hành

×