June 2009 - Posts
לאחר 5 שנים אינטנסיביות Wise Mobility סוגרת את שעריה, ואני חוזר לשוק העבודה.
מעטים האתרגים המקצועיים שמשתווים לאחריות הטוטאלית של בעלות בחברה שיסדתה עם מספר מצומצם של שותפים.
מצד אחד נהנים מחופש מלא בכל הקשור למודלי הפיתוח, ארכיטקטורה ותהליכי העבודה,
אך מצד שני אתה פועל תחת סד משאבים מוגבלים שאותם אתה מנסה לנצל באופן המיטבי.
בסך הכל אם אסכם את התקופה (כ 5 שנים) זוהי התנסות יחידה במינה שרבים חושבים עליה אך מעטים ממשים,
ואני מסכם אותה בחיוב.
This post explore advance techniques of changing the default MEF discovery behavior
into Castle Windsor like behavior (Castle Windsor is used as test case and it’s not the main subject of this post).
The code for this post available here (it built upon MEF preview 5.)
Prerequisites
This post assume that you have some knowledge on MEF and some understanding on DI (dependency injection)
Previous knowledge on Castle Windsor (which is one of the most common DI implementation) is not needed.
you can read more on MEF at the following posts: MEF Introduction, http://delicious.com/bnaya/mef.
Background
Out of the box, MEF come with a few very useful discovery model that relay on attribute decoration.
those model includes TypeCatalog, AssemblyCatalog, and DirectoryCatalog.
Brief description about MEF architecture:
MEF layers
The MEF architecture has 3 layers of abstraction:
- Hosting responsible for the actual composition and the actual API for the MEF consumers
- Primitive is the abstraction of the MEF components but dose not implement
the actual discovery and matching model
- Model layer responsible for the actual discovery and matching model,
MEF come with attribute model out of the box
Custom model
Creating custom module involve with inheritance of the following classes:
- Catalog which responsible for discovery and matching strategy
- ComposablePartDefinition which holding imports and exports definition
and use as factory for ComposablePart
- ExportDefinition holding the information about the export parts
- ImportDefinition define constraint which filler the ExportDefinition that satisfy the import
- ComposablePart which is responsible for instantiating the concrete export part
About the code sample
The code sample taking Castle Windsor model as test case for custom MEF model.
The sample solution has 2 projects:
- CastleMEF project which implement the MEF model
- CastleConsole which consume the CastleMEF module, using Castle Windsor configuration
CastleConsole configuration
<castle>
<components>
<component id="Logger"
service="Bnaya.Samples.ILogger, CastleConsole"
type="Bnaya.Samples.ColsoleLogger, CastleConsole">
</component>
</components>
</castle>
We can see very simple Castle Windsor configuration that map ILogger to be instantiate with ConsoleLogger
Castle Windsor instantiation Vs. MEF instantiation
Instantiating ILogger using Castle Windsor:
IWindsorContainer castleContainer = new WindsorContainer (new XmlInterpreter ());
ILogger castleLogger = castleContainer.Resolve<ILogger> ();
Instantiating ILogger using MEF:
ILogger mefSimpleLogger = CastelCompositor.Resolve<ILogger> ();
As we can see the consumer get quite similar experience.
Diving into the custom MEF implementation
Catalog:
public class CastelCatalog: ComposablePartCatalog {
private IQueryable<ComposablePartDefinition> _queryableParts = null;
public override IQueryable<ComposablePartDefinition> Parts {
get {
var collection = new List<ComposablePartDefinition> ();
collection.Add (new CastelPartDefinition (…));
return this._queryableParts;
}
}
}
The catalog responsible for give IQueryable of ComposablePartDefinition
ComposablePartDefinition
public class CastelPartDefinition: ComposablePartDefinition {
private Dictionary<string, object> _mapping; // the mapping as the catalog resolve from the configuration
public CastelPartDefinition ( Dictionary<string, object> mapping ) {
_mapping = mapping;
}
public override ComposablePart CreatePart () {
return new CastelPart (this);
}
public override IEnumerable<ExportDefinition> ExportDefinitions {
get {
return from item in _mapping
select new CastelExportDefinition (item.Key, item.Value) as ExportDefinition;
}
}
public override IEnumerable<ImportDefinition> ImportDefinitions {
get {
return from item in _mapping
select new CastelImportDefinition (item.Key) as ImportDefinition;
}
}
}
ExportDefinition
public class CastelExportDefinition: ExportDefinition {
private IDictionary<string, object> _metadata;
public CastelExportDefinition ( string contractName, object instance )
: base (contractName, null) {
_metadata = new Dictionary<string, object> (base.Metadata);
_metadata.Add ("Instance", instance); // holding the actual instance
_metadata.Add ("ExportTypeIdentity", contractName); // won't work without it
}
public override IDictionary<string, object> Metadata {
get {
return _metadata;
}
}
}
Export definition responsible to supply the right instance information to the right contract
ImportDefinition
public class CastelImportDefinition: ImportDefinition {
public CastelImportDefinition ( string contract )
: base (e => e.ContractName == contract,
ImportCardinality.ExactlyOne, false, false) {
}
}
Import definition responsible to set the filtering which satisfy the import (e => e.ContractName == contract)
ComposablePart
public class CastelPart: ComposablePart {
private readonly CastelPartDefinition _def;
public CastelPart (CastelPartDefinition def) {
_def = def;
} public override object GetExportedObject ( ExportDefinition definition ){
if (!definition.Metadata.ContainsKey ("Instance"))
return null;
return definition.Metadata["Instance"];
}
}
The role of the composable part is to hand the concrete instance
Summary
MEF built upon abstraction layer (primitives) therefore we can replace the
out of the box attributed model with our own.
It can be useful in cases that we need to compose the MEF upon
runtime information like central configuration, cases where the
design-time attribute model does not fit.
This post is the 3rd of series on serialization in WCF.
The post is taking the previous post concept one step ahead by wrapping the List<T> as serializable type
Downloads available here
Jump into the code
see the theory in the previous post
[XmlRoot (Namespace = "htp://...")]
public class GenListCustom<T>:List<T>,IXmlSerializable {
private static readonly string ITEM_ELEMENT_NAME=
typeof (T).Name;
XmlSchema IXmlSerializable.GetSchema() {
throw new NotImplementedException();
}
void IXmlSerializable.ReadXml(XmlReader reader){
var ser=new DataContractSerializer(typeof(T));
while(reader.Name == ITEM_ELEMENT_NAME){
var item = (T)ser.ReadObject(reader);
this.Add (item);
}
}
void IXmlSerializable.WriteXml ( XmlWriter writer ) {
var ser = new DataContractSerializer (typeof (T));
writer.WriteStartElement ("Items", "htp://...");
foreach (var item in this) {
ser.WriteObject (writer, item);
}
writer.WriteEndElement ();
}
}
Actually this class is identical to the class on our previous post with one exception, it use T instead of CompositeType.
WCF and generics collections
Unfortunately WCF does not always handling well generics collections of complex types (despite the fact that it can be serialized using Data Contract serialization).
In those case you may use the the technique of having the collection as composite type and using property decorated with DataMember attribute in order to serialize the collection (as discuss in Serialize generics list part 1)
Summary
I used post reuse pattern :-) leaving the theory in the previous post, but after reading the previous post I believe it’s kind of straight forward.
As Rotem suggest in his comment you should consider using the CollectionDataContract attribute.
Downloads available here
Previous Posts
del.icio.us Tags: WCF Data Contract Xml Serialization Serialize
This post is the second of series on serialization in WCF (previous post).
The topic of this post is dealing with writing data contract that inherit from type that does not decorated with the DataContract attribute (in our case List<T>).
Downloads available here
Why shouldn’t it work?
consider the following type declaration:
[DataContract]
public class ListCustom: List<CompositeType> {…}
The above code will not pass the data contract serialization because List<T> does not decorated with DataContract attribute
What can we do about it?
We can certainly refactor the class to composite pattern which will look like the following:
[DataContract]
public class ListCustom{
private List<CompositeType> m_aItems =
new List<CompositeType> ();
[DataMember]
private CompositeType[] Values {
get {
if (m_aItems == null)
m_aItems = new List<CompositeType> ();
return m_aItems.ToArray ();
}
set {
if (m_aItems == null)
m_aItems = new List<CompositeType> ();
m_aItems.AddRange (value);
}
}
}
This is simple work around but we have to refactor the code and lose the inheritance benefits.
Can we serialize none decorated types?
The answer is yes, and this is how we do it.
It is not the simplest task if you don’t familiar with xml serialization, but I will try to explain it.
Data contract serialization do know to serialize types that implement xml serialization, so it give us the option to instruct the serializer how to serialize the base type which is not decorated with DataContract attribute.
Please read the code and I will explain it latter:
[XmlRoot (Namespace = "http://...")]
public class ListCustom: List<CompositeType>, IXmlSerializable {
XmlSchema IXmlSerializable.GetSchema () {
throw new NotImplementedException ();
}
void IXmlSerializable.ReadXml ( XmlReader reader ) {
var ser = new DataContractSerializer (typeof (CompositeType));
...
while (reader.Name == "CompositeType") {
var item = ser.ReadObject (reader) as CompositeType;
this.Add (item);
}
}
void IXmlSerializable.WriteXml ( XmlWriter writer ) {
var ser = new DataContractSerializer (typeof (CompositeType));
writer.WriteStartElement ("Items", "http://...");
foreach (var item in this) {
ser.WriteObject (writer, item);
}
writer.WriteEndElement ();
}
}
What’s in the code?
- Instead of decorating the class with DataContract attribute we decorating it with XmlRoot attribute.
- We implementing IXmlSerializable so we can customize the serialization processing
- You can ignore GetSchema
- The serialization process is using ReadXml for deserialization and WriteXml for serialization.
you can just copy and paste the code pattern all it’s doing is using XmlReader and XmlWriter combine with DataContractSerializer in order to inject or fetch the list item to or from the xml stream.
Summary
We saw that we can keep our functionality in term of inheritance of none serializable type and still serialize it with data contract serialization.
Downloads available here
Part 2 will take it one step further and use
class ListCustom<T>: List<T>
Following Posts
Previous Posts
This post is the first of a series.
Each post of this series will take the concept one step ahead.
Code sample download available here
What in this post?
this post will discuss the technique of writing reusable type that can be serialize both by Data Contract serialization and Xml serialization and be later deserialize by the other.
Why should we care about it?
- This technique is the base line for following posts in this series which talk about serializing inherits generics list.
- Some .NET technologies (like the compact framework) does not support Data Contract serialization, so it is needed in order to achieve reusable business entity.
How to write flexible serializable entity?
[DataContract(Namespace="http://…", Name="CompositeType")]
[XmlRoot(Namespace="http://…", ElementName="CompositeType")]
public class CompositeType {
[DataMember (Order = 1)]
[XmlElement (IsNullable = true, Order = 1)]
public string StringValue { get; set; }
[DataMember (Order = 2)]
[XmlElement (DataType = "base64Binary", Order = 2)]
public byte[] BytesValue{ get; set; }
}
Lets talk about it :)
- The class should be decorated with both DataContract and XmlRoot attributes and it is important to set the namespace (otherwise you won’t be able to serialize with one technique and deserialize with the other)
- Properties should be decorated with both DataMember and XmlElement attribute given correlated order
Summary
Simple scenarios can be adjust with little addition of xml serialization attribute to your data contract entities (remember to assign the namespace)
The sample code is available here
the following post will discuss how to serialize collections
Following Posts
Previous Posts
del.icio.us Tags: WCF Data Contract Xml Serialization Serialize
The MEF team declare the MEF as
“The Managed Extensibility Framework (MEF) is a new library in .NET that enables greater reuse of applications and components. Using MEF, .NET applications can make the shift from being statically compiled to dynamically composed.”
you can download the MEF bits in here
SO what is the MEF and why do you want it?
Lets start with what !(MAF) MEF is not another DI (dependency injection), you should think of MEF as plug-ins infrastructure rather then being DI.
Actually you can consider MEF as very flexible plug-ins discovery mechanism.
How does it work?
The essence of MEF paradigm is built upon the idea of needs and part that can be founds (in order of satisfying the needs).
You can think of it as having Guilds that publish its policy (shoemaker, tailor, ext…), and Peoples that declaring their professions, the MEF infrastructure apply the role of matching the Peoples to their suitable Guilds.
The above diagram present institutions (University and software company) that has specific need (in terms of human segments), and peoples that apply to one or more of the segments. the MEF framework role is to satisfy the institution needs by discovering the people which apply the right segments.
The MEF terminology: institutions will be declare as Import and the peoples will be declare as Export Parts
Where does MEF looking for the for its Export Parts?
MEF is looking for export parts in Catalogs there is built-in catalogs (like Directory, Assembly, Types) and you definitely can build your own.
Code samples:
You can download the sample here (VS 2008 SP1)
the following are very light snippets of how it will look
// property that declare its needs for university related peoples
[Import (typeof (IUniversityRelated))]
public IEnumerable<PeopleBase> Peoples { get; private set; }// class that decorate export part for university
[Export (typeof (IUniversityRelated))]
public class Student: PeopleBase, IUniversityRelated
// asking the MEF to compose the right export parts
// in order of satisfying the imports
private static CompositionContainer s_container =
new CompositionContainer (new AggregateCatalog ());
static void Main ( string[] args ) {
…
// here the MEF magic matching game occur
s_container.Compose (new CompositionBatch ());
Summary
MEF is very friendly plug-ins framework which help you to get greater extensibility with less efforts and more consistency. It is very simple decoration module which having supper light dependencies.I hope you find this post useful, I'm having intensions to write future post which will cover the MEF in more details including some advance technique.
About
Bnaya Eshet C.T.O and co-founder of Wise Mobility