Caliburn笔记.docx
《Caliburn笔记.docx》由会员分享,可在线阅读,更多相关《Caliburn笔记.docx(50页珍藏版)》请在冰豆网上搜索。
Caliburn笔记
Caliburn笔记
此框架地址如下.先来学习一下其中的一些概念.
一.启动时加载服务
一切还是从容器开始,Caliburn提供了一个默认的Ioc容器,当然也可以用第三方的,如下
我们学习的目标则是了解Caliburn为我们提供了多少的功能服务,这些就是我们所需要了解的
二.Microsoft.Practices.ServiceLocation
单例模式在此框架中得到重用,使得到处可以使用依赖注入的功能
三.基本容器服务层
以上是基本已注册的服务
1.IServiceLocator 用于获取全局Service
2.SimpleContainer 一个实现IContainer接口的容器
3.IContainer 一个空容器,其继承了IConfigurator
4.IConfigurator ConfigureWith方法为第三方Ioc容器提供注册扩展
CaliburnFramework
.ConfigureCore()
.WithPresentationFramework()
.Start();
以上ConfigureCore则完成了上面的部分的主要配置
四.基本核心服务
当容器创建完成后,就好开始添加核心服务了
ConfigureCore方法会返回一个CoreConfiguration类,CoreConfiguration负责注册核心服务
以上是系统核心服务,基本还是看不到wpf的影子,属于基层
1.DefaultThreadPool=>IThreadPool提供一个多线程操作的线程池方法管理
2.MethodFactory=>IMethodFactory顾名思义,用于创建IMethod的工厂
3.EventHandlerFactory 用于创建事件
4.Execute.SimpleDispatcher=>IDispatcher用于执行UI线程操作的服务
5.DefaultAssemblySource=>IAssemblySource集合操作对Assembly进行一个检查
到此为止ConfigureCore方法真正完成
五.UI服务层
接下来才是重头戏,一下分篇幅讲
Caliburn笔记-元数据(Metadata)管理(wpf框架)
在.net中允许我们使用元数据(即Attribute),在使用Action时,结合元数据可以为框架功能提供一些便利.
caliburn提供了很多的元数据,其皆继承自IMetadata接口,该接口即一个空元数据标记接口而已,继承此接口的元数据则表明为属于caliburn功能范围内的元数据,方便管理.
IMetadataContainer接口提供了对IMetadata的管理
MetadataContainer为IMetadataContainer默认实现,继承MetadataContainer的类则均具有管理元数据的功能
///
///Animplementationof.
///
publicclassMetadataContainer:
PropertyChangedBase,IMetadataContainer
{
privateList_metadata;
///
///Addsthemetadatafromtheprovidedmembertothecollection.
///
///Themember.
protectedvirtualvoidAddMetadataFrom(MemberInfomember)
{
member.GetCustomAttributes(true)
.OfType()
.Apply(AddMetadata);
}
///
///Addsmetadatatothestore.
///
///Themetadata.
publicvirtualvoidAddMetadata(IMetadatametadata)
{
if(_metadata==null)
_metadata=newList();
_metadata.Add(metadata);
}
///
///Retrievesmetadatafromthestore.
///
///
///
publicvirtualTGetMetadata()
whereT:
IMetadata
{
return_metadata==null
?
default(T)
:
_metadata.OfType().FirstOrDefault();
}
///
///Getsthematchingmetadata.
///
///Thetypetomatch.
///Thematches
publicvirtualIEnumerableGetMatchingMetadata()
whereT:
IMetadata
{
return_metadata==null
?
newList()
:
_metadata.OfType();
}
}
Caliburn笔记-Action的创建(wpf框架)
若一个对象被设置成为DataContext,该对象的方法称之为Action,caliburn通过附加属性来绑定这些Action,首先则需要获取绑定对象的方法.如下示例对象,则有4个方法.
[Rescue("GeneralRescue")]
publicclassCalculator
{
//Note:
Thisrescuecatchesexceptionsthrownbythismethod.
//[Rescue("ActionSpecificRescue")]
//Note:
Previewindicatessomethingthatwillhappenbeforeexecutionoftheaction.
//Note:
IfAffectsTriggers=false,thenthisfilterwillnoteffectthestateoftheUIinrealtime.
//[Preview("CanDivide")]
//Note:
ThereturnvalueisboundtotheUIifpresent.
publicintDivide(intleft,intright)
{
returnleft/right;
}
//Note:
SeePreviewfilter.
publicboolCanDivide(intleft,intright)
{
returnright!
=0;
}
//Note:
Seeclasslevelrescuefilter.
publicvoidGeneralRescue(Exceptionex)
{
MessageBox.Show(ex.Message);
}
//Note:
SeerescuefilteronDividemethod.
publicvoidActionSpecificRescue(Exceptionex)
{
MessageBox.Show("DivideAction:
"+ex.Message);
}
}
Action只包含公开方法,并不包含属性与事件等,所以需要对象成员进行过滤.如下逻辑
protectedvirtualIEnumerable>SelectMethods(TypetargetType)
{
return
frommethodintargetType.GetMethods(BindingFlags.Public|BindingFlags.Instance|BindingFlags.Static)
wheremethod.DeclaringType!
=typeof(object)
&&!
method.ContainsGenericParameters
&&!
method.Name.StartsWith("get_")
&&!
method.Name.StartsWith("set_")
&&!
method.Name.StartsWith("remove_")
&&!
method.Name.StartsWith("add_")
&&method.GetParameters().All(x=>!
x.IsOut)
groupmethodbymethod.Name
intogroups
selectgroups;
}
方法与Action的转换
完成方法过滤后,为了添加功能,还要对方法进行转换.
首先根据方法,创建一个IMethod.然后创建Action.
当然Action还有其他功能,这里分为同步与异步.
protectedvirtualIActionCreateAction(IActionHosthost,MethodInfomethodInfo)
{
varmethod=_methodFactory.CreateFrom(methodInfo);
varasyncAtt=method.GetMetadata();
varfilters=host.GetFilterManager(method);
TryAddCanExecute(filters,method);
if(asyncAtt==null)
returnnewSynchronousAction(method,_messageBinder,filters);
returnnewAsynchronousAction(method,_messageBinder,filters,asyncAtt.BlockInteraction);
}
创建好以后再将其保存,创建过程由实现IActionFactory接口的ActionFactory完成.
publicIEnumerableCreateFor(IActionHosthost)
{
varactions=newList();
varmethodGroups=SelectMethods(host.TargetType);
foreach(varmethodGroupinmethodGroups)
{
varmethodList=methodGroup.ToList();
if(methodList.Count==1)
actions.Add(CreateAction(host,methodList[0]));
else
{
varoverloadedAction=newOverloadedAction(methodGroup.Key);
foreach(varmethodInfoinmethodList)
{
overloadedAction.AddOverload(CreateAction(host,methodInfo));
}
actions.Add(overloadedAction);
}
}
returnactions;
}
Caliburn笔记-方法(IMethod)的创建(wpf框架)
为了适应框架的需要,对原生的MethodInfo进行了改造,如下图
我们可以看到,主要的功能点是允许方法可以进行异步操作.其次IMethod也继承了IMetadataContainer接口,在方法上使用元数据也非常普遍.如下为默认实现的抽象类
///
///Abaseclassforimplementations.
///
privateabstractclassMethodProxyBase:
MetadataContainer,IMethod
{
privatereadonlyMethodInfo_info;
protectedreadonlyIThreadPool_threadPool;
///
///Initializesanewinstanceoftheclass.
///
///Theinfo.
///Thethreadpool.
protectedMethodProxyBase(MethodInfoinfo,IThreadPoolthreadPool)
{
_info=info;
_threadPool=threadPool;
AddMetadataFrom(_info);
}
///
///Getsthetowhichthisinstanceapplies.
///
///Theinfo.
publicMethodInfoInfo
{
get{return_info;}
}
///
///Invokesthespecifiedmethodontheprovidedinstancewiththegivenparameters.
///
///Theinstance.
///Theparameters.
///
///Theresultofthefunctionornullifitisaprocedure.
///
publicabstractobjectInvoke(objectinstance,paramsobject[]parameters);
///
///Createsabackgroundtaskforexecutingthismethodasynchronously.
///
///Theinstance.
///Theparameters.
///
///Aninstanceof.
///
publicabstractIBackgroundTaskCreateBackgroundTask(objectinstance,paramsobject[]parameters);
继承此类的分为有返回值与无返回值的方法
关键点:
1.对方法进行了委托转换
2.方法执行安全操作,可进行抛错
3.可以进行异步
privateclassFunction:
MethodProxyBase
{
privatereadonlyLateBoundFunc_theDelegate;
///
///Initializesanewinstanceoftheclass.
///
///Theinfo.
///Thethreadpool.
publicFunction(MethodInfoinfo,IThreadPoolthreadPool)
:
base(info,threadPool)
{
_theDelegate=DelegateFactory.Create(info);
}
///
///Invokesthespecifiedmethodontheprovidedinstancewiththegivenparameters.
///
///Theinstance.
///Theparameters.
///
///Theresultofthefunctionornullifitisaprocedure.
///
publicoverrideobjectInvoke(objectinstance,paramsobject[]parameters)
{
returnSafeInvoke(instance,parameters);
}
///
///Createsabackgroundtaskforexecutingthismethodasynchronously.
///
///Theinstance.
///Theparameters.
///
///Aninstanceof.
///
publicoverrideIBackgroundTaskCreateBackgroundTask(objectinstance,paramsobject[]parameters)
{
returnnewBackgroundTask(_threadPool,()=>SafeInvoke(instance,parameters));
}
privateobjectSafeInvoke(objectinstance,object[]parameters)
{
try
{
return_theDelegate(instance,parameters);
}
catch(Exception)
{
varrequirements=Info.GetParameters();
if(requirements.Length!
=parameters.Length)
thrownewCaliburnException(
string.Format(
"Themethod'{0}'expected{1}parametersbutwasprovided{2}.",
Info.Name,
requirements.Length,
parameters.Length)
);
throw;
}
}
}
DelegateFactory用于动态转换委托,其使用了表达式树(Expression)动态进行编译.
Caliburn笔记-消息触发器(wpf框架) 收藏
参考此
先看下面一段xaml
Message.Triggers>
RoutedMessageTriggerCollection>
EventMessageTriggerEventName="Click">
EventMessageTrigger.Message>
ActionMessageMethodName="Divide"
OutcomePath="DivideResult.Text">
--Note:
ThedeclarationofparametersisdifferentfromSilverlight.-->
ParameterValue="{BindingElementName=left,Path=Text}"/>
ParameterValue="{BindingElementName=right,Path=Text}"/>
ActionMessage>
EventMessageTrigger.Message>
EventMessageTrigger>
RoutedMessageTrigge