2010-09-09 30 views
6

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?

+0

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. –

Trả lời

1

Điều này dựa trên câu trả lời tự hỏi của người hỏi bên dưới, thay vì câu hỏi.

Nếu bạn xóa một dự án/mô-đun, các tệp DLL/XAP đầu ra sẽ bị treo xung quanh. Nếu bạn nhấp vào nút "hiển thị tất cả tệp", bạn sẽ thấy một số tệp đầu ra còn lại này trong các thư mục clientbin, binobj của các dự án liên quan.

alt text

Bạn có thể xóa chúng riêng rẽ từ các dự án, hoặc, khi nghi ngờ, tìm kiếm cho tất cả BIN và OBJ (ví dụ sử dụng máy tính để bàn explorer) và xóa tất cả các thư mục. Các thư mục BIN/CLIENTBIN/OBJ sẽ được tạo lại khi cần thiết (công việc này là tùy chọn "sạch" trong Visual Studio nên được thực hiện!)

Hy vọng điều này sẽ hữu ích.

+0

Tôi đã chọn câu trả lời của bạn là chính xác, tuy nhiên, tôi nhận thấy rằng trình đơn Build-> Clean của Visual Studio không giúp được. Xóa thư mục bin/obj có thể giúp ích (tôi chưa làm), tôi chỉ không muốn làm Vì vậy, hiện tại những gì tôi đang làm là thay đổi số cổng của máy chủ web. Bằng cách này, vấn đề này xảy ra thường xuyên, ngay cả khi tôi đổi tên không có gì. – synergetic

1

Ok, tôi đã tìm ra nguyên nhân. Mã trên hoạt động. Sau khi tạo một dự án Silverlight mới (Sales.xap) tôi đã xảy ra để biên dịch giải pháp của tôi một lần. Sau đó, tôi đã xóa lớp ứng dụng trong Sales.xap và đổi tên thành lớp MainPage mặc định thành SalesView. Tuy nhiên, không có vấn đề bao nhiêu lần tôi biên dịch giải pháp của tôi, máy chủ web phát triển của Visual Studio đã tải phiên bản đầu tiên của Sales.xap (từ đâu đến?), Vì vậy mã của tôi không thể tìm thấy SalesView. Trong dự án máy chủ lưu trữ Asp.Net của tôi, tôi đặt cổng của máy chủ phát triển sang một số cổng khác và sự cố đã biến mất. Vì vậy, vấn đề là với máy chủ phát triển của Visual Studio. Rõ ràng nó đang giữ các tập tin xap biên soạn trong một số thư mục tạm thời, và không phải luôn luôn cập nhật các tập tin xap khi mã nguồn thay đổi.

+0

Tôi gặp vấn đề tương tự, tôi đang sử dụng chrome - @Xds là đúng .Các vấn đề có vẻ là với các tập tin chrome caching xap lớn thời gian! Nếu bạn mở một cửa sổ ẩn danh cho cùng một URL, bạn sẽ thấy những thay đổi mới nhất (vì ẩn danh không có bộ nhớ cache). Ngoài ra, nếu bạn sử dụng IExplorer cho cùng một url, nó sẽ hiển thị mới nhất - nó không có bộ đệm ẩn. Người ta hy vọng rằng google chrome không lưu trữ bộ nhớ đệm một cách cứng nhắc. :( – DeeStackOverflow

0

Những gì tôi làm gì để tránh vấn đề như vậy khi thực hiện tươi biên soạn Silverlight là rõ ràng bộ nhớ cache của trình duyệt, chrome thậm chí còn có một bộ nhớ cache Silverlight rõ ràng;)

0

XAP này cache hiện tượng thường là do sự visual studio máy chủ web nhúng (ASP.NET phát triển máy chủ). Chỉ cần dừng sự xuất hiện của máy chủ này và bộ nhớ cache sẽ bị xóa. Bắt đầu lại dự án của bạn và bản dựng xap mới nhất của bạn được gọi.

Các vấn đề liên quan