示例程序1:
program.cs
public class Program : FormShellApplication<WorkItem, Form1>
{
[STAThread]
static void Main()
{
new Program().Run();
}
protected override void AfterShellCreated()
{
base.AfterShellCreated();
this.Shell.IsMdiContainer = true;
RootWorkItem.Items.Add(this.Shell, "Shell");
}
}
ProfileCatelog.xml
<?xml version="1.0" encoding="utf-8" ?>
<SolutionProfile xmlns="http://schemas.microsoft.com/pag/cab-profile">
<Modules>
<ModuleInfo AssemblyFile="Red.exe" />
<ModuleInfo AssemblyFile="Blue.exe" />
</Modules>
</SolutionProfile>
将red和blue项目中Module的ModuleInit
public class RedModuleInit : ModuleInit
{
private WorkItem parentworkitem;
public override void Load()
{
base.Load();
Form shell = (Form)parentworkitem.Items["Shell"];
Form1 form = new Form1();
form.MdiParent = shell;
form.Show();
}
[ServiceDependency]
public WorkItem Parentworkitem
{
set { parentworkitem = value; }
}
}
1,简介:Composite Application Block :复合应用程序
定义服务:
public interface IMyService
{
string GetHello();
}
{
string GetHello();
}
public class MyService : IMyService
{
public string GetHello()
{
return "Hello World";
}
}
{
public string GetHello()
{
return "Hello World";
}
}
添加服务:
protected override void AfterShellCreated()
{
//RootWorkItem.Services.AddNew<MyService>();
RootWorkItem.Services.AddNew<MyService, IMyService>();
{
//RootWorkItem.Services.AddNew<MyService>();
RootWorkItem.Services.AddNew<MyService, IMyService>();
UseMyService();
...
...
引用使用服务:
private void UseMyService()
{
IMyService service = RootWorkItem.Services.Get<IMyService>();//根据接口名获取服务类
System.Diagnostics.Debug.WriteLine(service.GetHello());
}
Ways of Creating a Service (1) – Add Methods RootWorkItem.Services.AddNew<MyService>();
{
IMyService service = RootWorkItem.Services.Get<IMyService>();//根据接口名获取服务类
System.Diagnostics.Debug.WriteLine(service.GetHello());
}
Ways of Creating a Service (1) – Add Methods RootWorkItem.Services.AddNew<MyService>();
Ways of Creating a Service (2) – XML Configuration File
<?xml version="1.0" encoding="utf-8" ?>
<configuration>
<configSections>
<section name="CompositeUI" type="Microsoft.Practices.CompositeUI.Configuration.SettingsSection, Microsoft.Practices.CompositeUI" allowExeDefinition="MachineToLocalUser" />
</configSections>
<CompositeUI>
<services>
<add serviceType ="Shell.MyService, Shell" instanceType ="Shell.MyService, Shell" />
</services>
</CompositeUI>
</configuration>
<configuration>
<configSections>
<section name="CompositeUI" type="Microsoft.Practices.CompositeUI.Configuration.SettingsSection, Microsoft.Practices.CompositeUI" allowExeDefinition="MachineToLocalUser" />
</configSections>
<CompositeUI>
<services>
<add serviceType ="Shell.MyService, Shell" instanceType ="Shell.MyService, Shell" />
</services>
</CompositeUI>
</configuration>
Ways of Creating a Service (3) – the Service Attribute
[Service(typeof(IMyService), AddOnDemand=true)]
public class MyService : IMyService
{
public string GetHello()
{
return "Hello World";
}
}
public class MyService : IMyService
{
public string GetHello()
{
return "Hello World";
}
}
Ways of Retrieving a Service (1) – Get Method
private void UseMyService()
{
IMyService service = RootWorkItem.Services.Get<IMyService>();
System.Diagnostics.Debug.WriteLine(service.GetHello());
}
{
IMyService service = RootWorkItem.Services.Get<IMyService>();
System.Diagnostics.Debug.WriteLine(service.GetHello());
}
Ways of Retrieving a Service (2) – Dependency Injection
public class ServiceClient
{
private IMyService service;
[ServiceDependency]
public IMyService Service
{
set
{
service = value;
}
}
internal string UseMyService()
{
return service.GetHello();
}
}
{
private IMyService service;
[ServiceDependency]
public IMyService Service
{
set
{
service = value;
}
}
internal string UseMyService()
{
return service.GetHello();
}
}
RootWorkItem.Items.AddNew<Compoent2>("Component2");
6,CAB中的构造器注入
通过InjectionConstructorAttribute特性
public class Component2
{
private Component1 component11;
//[ComponentDependency("FirstComponent1")]
//public Component1 Component11
//{
// set { component11 = value; }
//}
private Component1 component12;
//[CreateNew]
//public Component1 Component12
//{
// set { component12 = value; }
//}
[InjectionConstructor]
public Component2([ComponentDependency("FirstComponent1")]Component1 component, [CreateNew]Component1 component2)
{
component11 = component;
component12 = component2;
}
}
part 7:
服务:在CA中服务的定义是:一个支持的类,这个类提供某种功能给其他的组件,通过一种松耦合的方式。
CABPedia:服务允许容易的访问一些可能在整个程序中被经常使用的功能。错误处理,日志,和事件代理就是一些好的功能例子,那能被列出来作为一个服务。
。
Services collections Vs Items collections
1,Unique types
Services collections can only ever contain one object of a given type. if we attemp to add a second service of the same type to a service collection we get a Argument Exception with message 'A service of this type already exists'.
Items collection of a workItem can contain multiple objects of the same type. To accommodate
part 11. Events
定义(订阅)一个事件:Note that the method has to be public, and to have a method signature as shown.
[EventSubscription("MyEvent")]
public void MyEventHandler(object sender, EventArgs e)
{
MessageBox.Show("Hello from the CAB event handler");
}
public void MyEventHandler(object sender, EventArgs e)
{
MessageBox.Show("Hello from the CAB event handler");
}
触发一个事件:
workItem.EventTopics["MyEvent"].Fire(this, EventArgs.Empty, null, PublicationScope.Global);first two parameters will be passed into the method.and the third and the fourth methods to be use for searching for appropriate Event PublicationScope enum.
workItem.EventTopics["MyEvent"].Fire(this, EventArgs.Empty, childWorkItem1, PublicationScope.WorkItem);
When this code is executed the event will fire and all methods decorated with the EventSubscription(“MyEvent”) attribute will get executed.
Invoking onto the user interface thread
让用户界面调用,定义事件时:
[EventSubscription("MyEvent", ThreadOption.UserInterface)]
public void MyEventHandler(object sender, EventArgs e)
{
MessageBox.Show("Hello from the CAB event handler");
}
public void MyEventHandler(object sender, EventArgs e)
{
MessageBox.Show("Hello from the CAB event handler");
}
线程枚举参数:ThreadOption.UserInterface ThreadOption.Publisher ThreadOption.Background
不用attribute ,动态添加删除事件发布:
RootWorkItem.EventTopics["MyEvent"].AddSubscription(subscriber, "MyEventHandler", workItem1, ThreadOption.UserInterface
eventTopic.RemoveSubscription(subscriber, "MyEventHandler");
直接给按钮添加相应事件:
RootWorkItem.EventTopics["MyEvent"].AddPublication(Shell.cabEventFirerButton, "Click", RootWorkItem, PublicationScope.Global);
设置EventTopic是否启动的属性
private void eventsEnabledCheckbox_CheckedChanged(object sender, EventArgs e)
{
rootWorkItem.EventTopics["MyEvent"].Enabled = eventsEnabledCheckbox.Checked;
}
{
rootWorkItem.EventTopics["MyEvent"].Enabled = eventsEnabledCheckbox.Checked;
}
part 13: UIExtensionSites
A UIExtension is a user interface element of the shell(the contaning window) for a composite application.
注册工具栏按钮:
RootWorkItem.UIExtensionSites.RegisterSite("ShellToolStrip", this.Shell.shellToolStrip);
ToolStripButton toolStripButton = new ToolStripButton("Show Blue Screen");
toolStripButton.Click += new System.EventHandler(toolStripButton_Click);
UIExtensionSite uiExtensionsite = parentworkitem.UIExtensionSites["toolStrip1"];
uiExtensionsite.Add<ToolStripButton>(toolStripButton);
toolStripButton.Click += new System.EventHandler(toolStripButton_Click);
UIExtensionSite uiExtensionsite = parentworkitem.UIExtensionSites["toolStrip1"];
uiExtensionsite.Add<ToolStripButton>(toolStripButton);
Types that can be added to a UIExtensionSite:
LinkLabelPanel User Control
public partial class LinkLabelPanel : UserControl
{
public LinkLabelPanel()
{
InitializeComponent();
}
private const int labelSpacing = 22;
private int nextLabelTop = 10;
private const int left = 3;
public void AddLabel(LinkLabel label)
{
label.Location = new Point(left, nextLabelTop);
nextLabelTop += labelSpacing;
this.Controls.Add(label);
}
public void RemoveLabel(LinkLabel label)
{
this.Controls.Remove(label);
}
}
{
InitializeComponent();
}
private const int labelSpacing = 22;
private int nextLabelTop = 10;
private const int left = 3;
public void AddLabel(LinkLabel label)
{
label.Location = new Point(left, nextLabelTop);
nextLabelTop += labelSpacing;
this.Controls.Add(label);
}
public void RemoveLabel(LinkLabel label)
{
this.Controls.Remove(label);
}
}
The Adapter for UIExtensionSite
public class LinkLabelPanelUIAdapter : UIElementAdapter<LinkLabel>
{
LinkLabelPanel panel;
public LinkLabelPanelUIAdapter(LinkLabelPanel panel) { this.panel = panel;
}
protected override LinkLabel Add(LinkLabel uiElement)
{
panel.AddLabel(uiElement);
return uiElement;
}
protected override void Remove(LinkLabel uiElement)
{
panel.RemoveLabel(uiElement);
}
}
{
LinkLabelPanel panel;
public LinkLabelPanelUIAdapter(LinkLabelPanel panel) { this.panel = panel;
}
protected override LinkLabel Add(LinkLabel uiElement)
{
panel.AddLabel(uiElement);
return uiElement;
}
protected override void Remove(LinkLabel uiElement)
{
panel.RemoveLabel(uiElement);
}
}
part 15: