Tôi biết rằng có thể tải các mô-đun xap động bằng khung Prism hoặc MEF. Tuy nhiên, tôi không muốn sử dụng các khung công tác đó; thay vì tải các tệp xap của tôi theo cách thủ công. Vì vậy, tôi đã tạo lớp học sau (được điều chỉnh từ internet):silverlight 4, nạp động mô-đun xap
public class XapLoader
{
public event XapLoadedEventHandler Completed;
private string _xapName;
public XapLoader(string xapName)
{
if (string.IsNullOrWhiteSpace(xapName))
throw new ArgumentException("Invalid module name!");
else
_xapName = xapName;
}
public void Begin()
{
Uri uri = new Uri(_xapName, UriKind.Relative);
if (uri != null)
{
WebClient wc = new WebClient();
wc.OpenReadCompleted += onXapLoadingResponse;
wc.OpenReadAsync(uri);
}
}
private void onXapLoadingResponse(object sender, OpenReadCompletedEventArgs e)
{
if ((e.Error == null) && (e.Cancelled == false))
initXap(e.Result);
if (Completed != null)
{
XapLoadedEventArgs args = new XapLoadedEventArgs();
args.Error = e.Error;
args.Cancelled = e.Cancelled;
Completed(this, args);
}
}
private void initXap(Stream stream)
{
string appManifest = new StreamReader(Application.GetResourceStream(
new StreamResourceInfo(stream, null), new Uri("AppManifest.xaml",
UriKind.Relative)).Stream).ReadToEnd();
XElement deploy = XDocument.Parse(appManifest).Root;
List<XElement> parts = (from assemblyParts in deploy.Elements().Elements()
select assemblyParts).ToList();
foreach (XElement xe in parts)
{
string source = xe.Attribute("Source").Value;
AssemblyPart asmPart = new AssemblyPart();
StreamResourceInfo streamInfo = Application.GetResourceStream(
new StreamResourceInfo(stream, "application/binary"),
new Uri(source, UriKind.Relative));
asmPart.Load(streamInfo.Stream);
}
}
}
public delegate void XapLoadedEventHandler(object sender, XapLoadedEventArgs e);
public class XapLoadedEventArgs : EventArgs
{
public Exception Error { get; set; }
public bool Cancelled { get; set; }
}
Mã trên hoạt động tốt; Tôi có thể tải bất kỳ XAP theo cách sau:
XapLoader xapLoader = new XapLoader("Sales.xap");
xapLoader.Completed += new XapLoadedEventHandler(xapLoader_Completed);
xapLoader.Begin();
Bây giờ, tôi có một UserControl gọi InvoiceView trong dự án Sales.xap, vì vậy tôi muốn nhanh chóng lớp. Trong dự án hiện tại (Main.xap), tôi đã thêm tham chiếu đến dự án Sales.xap, tuy nhiên, vì tôi tải nó theo cách thủ công, tôi thiết lập "Copy Local = False". Nhưng khi được thực thi, đoạn mã sau sẽ ném TypeLoadException:
Sales.InvoiceView view = new Sales.InvoiceView();
Dường như mã không thể tìm thấy lớp InvoiceView. Nhưng tôi đã kiểm tra phương thức initXap() của XapLoader đã được thực hiện thành công. Vậy tại sao mã không thể tìm thấy lớp InvoiceView? ai đó có thể giúp tôi vấn đề này không?
Cách dễ dàng hơn để thực hiện việc này là sử dụng Khung mở rộng được quản lý (MEF) được tích hợp vào Silverlight 4, ngoài .NET 4. –