silverlight 4, динамически загружаемые модули xap - PullRequest
6 голосов
/ 09 сентября 2010

Я знаю, что можно динамически загружать модули xap, используя Prism или MEF Framework.Однако я бы не хотел использовать эти рамки;вместо этого загрузите мои файлы 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; }
}

Приведенный выше код работает нормально;Я могу загрузить любой xap следующим образом:

XapLoader xapLoader = new XapLoader("Sales.xap");
xapLoader.Completed += new XapLoadedEventHandler(xapLoader_Completed);
xapLoader.Begin();

Теперь у меня есть UserControl с именем InvoiceView в проекте Sales.xap, поэтому я хотел бы создать экземпляр класса.В текущем проекте (Main.xap) я добавил ссылку на проект Sales.xap, однако, поскольку я загружаю его вручную, я установил «Copy Local = False».Но при выполнении следующий код выдает исключение TypeLoadException:

Sales.InvoiceView view = new Sales.InvoiceView();

Кажется, что код не может найти класс InvoiceView.Но я проверил, что метод initXap () XapLoader был успешно выполнен.Так почему же код не может найти класс InvoiceView?Может кто-нибудь помочь мне с этой проблемой?

Ответы [ 4 ]

1 голос
/ 09 сентября 2010

Это основано на ответе автора ниже, а не на вопросе.

Если вы удалите проект / модуль, выходные DLL-файлы / XAP-файлы будут зависать.Если вы нажмете кнопку «Показать все файлы», вы увидите некоторые из этих оставшихся выходных файлов в папках clientbin , bin и obj связанных проектов.

alt text

Вы можете удалить их по отдельности из проекта или, если сомневаетесь, найти все BIN и OBJ (например, с помощью Desktop Explorer) и удалить все эти папки.Папки BIN / CLIENTBIN / OBJ будут воссозданы при необходимости (эту работу должен выполнить «чистый» параметр в Visual Studio!)

Надеюсь, это поможет.

1 голос
/ 09 сентября 2010

Хорошо, я нашел причину. Приведенный выше код работает. После создания нового проекта Silverlight (Sales.xap) я однажды скомпилировал свое решение. Затем я удалил класс App в Sales.xap и переименовал класс MainPage по умолчанию в SalesView. Однако, независимо от того, сколько раз я компилировал свое решение, веб-сервер разработки Visual Studio загружал первую версию Sales.xap (откуда?), Поэтому мой код не мог найти SalesView. В моем проекте Asp.Net хоста я установил порт сервера разработки на другой номер порта, и проблема исчезла. Таким образом, проблема была с сервером разработки Visual Studio. По-видимому, он хранит скомпилированные файлы xap в какой-то временной папке и не всегда обновляет эти файлы xap при изменении исходного кода.

0 голосов
/ 11 октября 2011

это явление XAP Cache часто происходит из-за встроенного веб-сервера visual studio (ASP.NET Development Server).Просто остановите вхождение этого сервера, и кеш будет очищен.Начните заново ваш проект, и последняя сборка вашего xap называется.

0 голосов
/ 21 сентября 2010

Что я делаю, чтобы избежать подобных проблем при запуске только что скомпилированного Silverlight: очищается кеш браузера, в chrome даже есть прозрачный кеш silverlight;)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...