(转)Silverlight - Dynamically Loading an Assembly
时间:2011-01-10 来源:allanli
For example - a calculation engine or perhaps something more complicated like a piece of UI with interaction.
You can dynamically load up a .NET assembly in Silverlight at runtime, pull out known types from it and interact with them just like you would in any other .NET application.
I made my example as simple as possible. I defined a core UI which looks like this;
The idea is that the red bit is the "host" and the yellow bit is for the plug-in editor. I define an interface to live between my host and my plug-in editor;
public class TextEventArgs : EventArgs { public string TheText { get; set; } } public interface IEditUI { UIElement GetControls(); void SetText(string text); event EventHandler<TextEventArgs> TextChanged; }
and then an implementation of that which I put into an assembly called Implementation which is not referenced by my Silverlight application.
public class Editor : IEditUI { public Editor() { textBox = new TextBox(); } public UIElement GetControls() { StackPanel stackPanel = new StackPanel(); stackPanel.Margin = new Thickness(5); stackPanel.Orientation = Orientation.Horizontal; textBox = new TextBox(); textBox.Width = 100; Button button = new Button(); button.Content = "Click Me"; button.Click += OnButtonClick; stackPanel.Children.Add(textBox); stackPanel.Children.Add(button); return (stackPanel); } void OnButtonClick(object sender, RoutedEventArgs e) { if (TextChanged != null) { TextChanged(this, new TextEventArgs() { TheText = textBox.Text }); } } public void SetText(string text) { textBox.Text = text; } private TextBox textBox; public event EventHandler<TextEventArgs> TextChanged; }
Then, at runtime I can write code which will load this up and make use of it as in;
public partial class Page : UserControl { public Page() { InitializeComponent(); } void OnLoadDynamicEditor(object sender, EventArgs args) { WebClient client = new WebClient(); client.OpenReadCompleted += new OpenReadCompletedEventHandler(OnAssemblyOpened); client.OpenReadAsync(new Uri("Implementation.dll", UriKind.Relative)); } void OnAssemblyOpened(object sender, OpenReadCompletedEventArgs e) { AssemblyPart assemblyPart = new AssemblyPart(); Assembly assembly = assemblyPart.Load(e.Result); editor = assembly.CreateInstance("Implementation.Editor") as IEditUI; if (editor != null) { hostGrid.Children.Add(editor.GetControls()); editor.TextChanged += OnEditorTextChanged; } } void OnSendToEditor(object sender, EventArgs args) { if (editor != null) { editor.SetText(txtHost.Text); } } void OnEditorTextChanged(object sender, TextEventArgs e) { txtHost.Text = e.TheText; } IEditUI editor; }
Note: The Implementation.dll assembly needs to be manually copied to the ClientBin folder of the website project in order for this to work.