
Expert Days is an annual software development conference held by E4D in Israel. This year, for the first time, some of CodeValue’s experts have joined forces with E4D and are participating in order to give you, the attendee, the best possible value. If you are a software developer, software architect, team leader or somehow interested in the hottest available Microsoft technologies – this is definitely the conference you want to be at.
The conference is held on 10/07/2011-14/07/2011, and there are dozens of one-day workshops, which are packed with practical knowledge which you can immediately use. Investing your time in these workshops will certainly payoff immediately!
For more information regarding the available workshops, feel free to click the banner below.

Among all of the conference’s experts, you can also find me there this year and I gladly invite you to participate in my workshop – Developing .NET Systems in Real-Life. Note that if you specify that you arrived through me and specify my instructor code (121) you can get a 20% discount to my workshop!
Except for my workshop, I personally recommend arriving at workshops performed by some of the other CodeValue experts – Alon Fliess, Eran Stiller, Eli Arbel, Josh Reuben & Shay Friedman.
But wait – there’s more!
This year, Expert Days has a free opening event on 10/07/2011. This event includes a cocktail party, mingling and a series of professional lectures all of which are absolutely free. During the opening event, an XBOX+Kinnect set will be given to one of the attendees. That’s right – an XBOX+Kinnect set shall be given away to one of you! All you have to do is register and show up…

See you there,
Amir
In one of our projects, we encountered odd exceptions that were thrown out of “GetExportedValue<T>” from the CompositionContainer of MEF.
There are 2 exceptions that I have seen that are related to the same issue:
System.InvalidOperationException: GetExportedValue cannot be called before prerequisite import 'MyType..ctor(Parameter="myParameter", ContractName="MyOtherType")' has been set
System.ArgumentException: An item with the same key has already been added.
After digging into the matter, we found that these errors occurred while trying to call GetExportedValue concurrently from numerous threads.
Yeah, simple as that, MEF isn’t thread-safe in its default form.
Following is a sample code which demonstrates the error -
Code Snippet
- interface IFoo { }
-
- [Export(typeof(IFoo))]
- [PartCreationPolicy(CreationPolicy.Shared)]
- class Foo : IFoo { }
Code Snippet
- var catalog = new AssemblyCatalog(typeof(Program).Assembly);
-
- CompositionContainer container = new CompositionContainer(catalog);
-
- List<Task> tasks = new List<Task>();
- for (int i = 0; i < 5; i++)
- {
- tasks.Add(Task.Factory.StartNew(() => container.GetExportedValue<IFoo>()));
- }
-
- try
- {
- Task.WaitAll(tasks.ToArray());
-
- Console.WriteLine("No errors, thread safe");
- }
- catch (AggregateException ex)
- {
- Console.WriteLine("Error occurred: {0}", ex.InnerException.ToString());
- }
In this example, “Task.WaitAll” would throw an exception because of the concurrent hit on GetExportedValue.
How to fix this -
Well, the fix is as easy as it can be. You need to construct the container as thread safe -
Code Snippet
- CompositionContainer container = new CompositionContainer(catalog, true);
In the second parameter we pass ‘true’ to make it thread-safe.
That’s it! dead easy.
You should note that it has a performance hit though, obviously.
I decided to blog alittle about my ongoing experience here in TechEd Eilat.
Yesterday, on day 1, I arrived to Eilat and immediately got the great atmosphere this conference has put out for us.
Day 1
I attended the evening key-note session and was very impressed by the operation the Microsoft has gathered and pulled it off beautifully. It wasn't hard to see that there was a great investment in this conference, and I'm simply glad.
The key-note was refreshing with good entertainment. There wasn't much that came new to me, but it was certainly nice to see how Microsoft sees the next generation in a new world of sharing and collaboration being materialized.
Day 2
I attended 2 sessions - Windows Azure Guidance Part 1 and 2. I liked these presentations very much, they met my expectations perfectly.
There wasn't any code, as much as I love to see code in sessions, that's what I expected. The presenter talked about all the key components in Windows Azure, explaining about them and how you should generally use them. That's what I was aiming for, just to get a bit more organized about things, and these sessions did just that.
Another session that I attended today was Deep Dive on Workflow Services. It was rather disappointing, don't get me wrong, the session was interesting and well built but I was expecting a more of a deep dive than what was actually there.
All in all, so far I'm having a blast. Soon there's the big party and I'm sure it would be great.
For day 3, I plan to go see the tooling presentation made by Alon Fliess, the CTO of our new company. I'm pretty sure I'll recognize everything there, but knowing Alon, this will be very professional and amusing to watch.
Another session that I plan to attend is about storage in Azure, I guess it'll be good too.
To summarize, the TechEd met my expectations in terms of content sessions and the execution of everything around it had been fabulous up until now. Microsoft - good job! thank you.
With the emerging of cloud computing, our perception of software design needs to shift and take account for the affects we need to deal with.
The signs are clear, with investments of billions of dollars by leading companies, such as Microsoft, Google, Amazon - Cloud computing is the future of the IT industry and many other specific product companies that can leverage its benefits.
If you looked into it, you must know by now – the pricing models for hosting applications in the cloud varies and you can choose from different packages to meet the requirements of your specific application.
How do you choose the right one? Well, that isn’t a simple question and it very much depends on the characteristics of your application.
Does it have enormous data behind it? Is it mostly data-centric with a lot of transactions? How busy is the front-end? How many cores would you need? Do you expect different request peaks at different times? And the list goes on..
Developing for the cloud requires good architecture if you want to leverage its true powers.
While there's a general architecture on how to program things in order to gain good practices, such as scalability, good performance and fault tolerance, this
post is written specifically to present the Cost-Oriented Development and Architecture approach as a
new relevant concept.
This subject no short and simple, in future posts I plan to include technical examples, best
practices and design principles as well.
Why should you care?
In most companies, the hardware is purchased and deployed to support the expected traffic and requirements and the applications are developed with no unique thought to address the cost-related circumstances.
This approach should change. With cloud computing, the operating system and hardware is ready for you in an environment where you essentially pay-per-use for the resources you utilize. (May vary according to the specific pricing package you purchased)
In such world, inefficient code and resource-utilization should be your concern! This has a much more direct affect, inefficient code means less money in your pocket.
To clarify, inefficient in that sense stands for cost-inefficiency, thus the term – Cost-Oriented Development.
Cost-inefficiency can obviously stand for performance-based issues, but also simple yet unaware mistakes of resource utilization or bad practices when it comes to cloud development.
Product companies which want to be cost-optimized, need to understand the implications of the code in terms of how it can affect the hosting price.
You can see some examples in the following article - Windows Azure: Cost Architecting for Windows Azure
When developing for the cloud – there is no such thing as “cheap developers”, this can end up costing you a lot of money down the road, unless you plan to invest in code review, guidance, and perhaps seeking for consult.
So what next?
This is the main aspect my new company assists with and this is only the beginning.
CloudValue is a Cost-Oriented Development solution company. We provide tools & methodologies for cost optimized applications targeting the new Cloud platforms, and essentially help you to save a lot of money.
In addition to providing professional services all around, our leading product, Cloudoscope™, the first Cost-Profiler ever, will help you write cost-optimized code and provide you with the ability to review your code, statically or dynamically, to predict problematic spots, inspect actual cost-value of every request and generally help you understand exactly what you are paying for and how you can make it even better.
Enough with the teasers, read more about us – CloudValue
I’d like to thank Michal and Microsoft for sending me to the TechEd in Eilat next week.
There are some presentations which seem cool and I’m happy to get the chance to hear them out in person.
I plan to blog about interesting sessions, so tune in if you like.

There was a project that I assisted with the WCF communications where they needed to allow the client to specify different credentials without being dependent on the windows account.
The first thing that comes into mind is to use the UserNameToken technique to pass in the client credentials. The design instructed to use TCP as the transport and not use message security. Obviously, this technique has privacy and integrity issues where there isn’t any encryption nor signing, but that was their decision because it wasn’t an issue in the purpose of the project.
Well, this setting isn’t as trivial as you would expect.
The default form of the NetTcpBinding allows you to use UserNameToken only as part of message security and forces you to use a certificate to enable that message security.
I ended up setting them a CustomBinding which provides the scenario they needed.
Service Side
Configuring the Service Host -
Code Snippet
- _host = new ServiceHost(typeof(Service));
- _host.AddServiceEndpoint(typeof(IService), Config.ServiceBinding, Config.ServiceAddress.Uri.AbsoluteUri);
-
- _host.Credentials.UserNameAuthentication.UserNamePasswordValidationMode = UserNamePasswordValidationMode.Custom;
- _host.Credentials.UserNameAuthentication.CustomUserNamePasswordValidator = new CustomUserNameTokenValidator();
-
- _host.Open();
Custom Simple Validator (you can write any logic you need here) -
Code Snippet
- class CustomUserNameTokenValidator : UserNamePasswordValidator
- {
- public override void Validate(string userName, string password)
- {
- Console.WriteLine("CustomUserNameTokenValidator.Validate - {0} / {1}", userName, password);
-
- if (string.IsNullOrEmpty(userName))
- {
- throw new SecurityTokenValidationException("Invalid username");
- }
- }
- }
In the service code, you can extract the caller’s identity name as follows -
Code Snippet
- class Service : IService
- {
- public void Do()
- {
- Console.WriteLine("Service.Do() - Identity Name: {0}",
- ServiceSecurityContext.Current.PrimaryIdentity.Name);
- }
- }
Client Side
In the client side you need to use the same binding, provide the UserNameToken credentials and simply call the service -
Code Snippet
- ChannelFactory<IService> factory = new ChannelFactory<IService>(Config.ServiceBinding, Config.ServiceAddress);
- factory.Credentials.UserName.UserName = "myUser";
- factory.Credentials.UserName.Password = "myPassword";
-
- IService proxy = factory.CreateChannel();
-
- proxy.Do();
-
- ((ICommunicationObject)proxy).Close();
Configuration
Following is the CustomBinding which enables this scenario -
Code Snippet
- SecurityBindingElement securityElement = SecurityBindingElement.CreateUserNameOverTransportBindingElement();
- ((TransportSecurityBindingElement)securityElement).AllowInsecureTransport = true;
-
- _serviceBinding = new CustomBinding(new BindingElement[] {
- securityElement,
- new BinaryMessageEncodingBindingElement(),
- new TcpTransportBindingElement()
- });
Feel free to download the source code and see that in action.
As part of the task where I had to upgrade an existing WPF project to PRISM 4.0 and work with MEF, one of the requirements was to support registering existing non-attributed parts.
Consider the following example -
Code Snippet
- public interface IFoo { }
-
- public class Foo : IFoo { }
-
- static void Main(string[] args)
- {
- //This is the desired thing to do
- myCatalog.Register<IFoo, Foo>();
- }
As you can see, type Foo has no export definitions set on it.
One approach would be to go over all the registrations and add attributes where needed, or create wrappers for legacy components, but the goal in our case was to support this kind of registration.
After digging around, I found two ways that you can go about it -
- Implement a conventional catalog using the ReflectionModelServices which is the MEF’s API for building reflection related parts information.
- Example - CodePaste.NET - A conventional catalog for MEF (Prototype)
- Use the MEF’s AttributedModelServices with a TypeDelegator to expose the actual type as an attributed type even though it doesn’t have attributes defined directly on it.
This is quite a sophisticated solution and I decided to stick with that one. - Example - Poco, Mef, and custom type systems. Are you ready to take the red pill
You can look at the links to see the actual code of each solution. Plus, you can integrate it with the type catalog which supports type registration in runtime which I described in my previous post.
Recently, I dug deep into MEF because I was involved in a project where there was a decision to upgrade the WPF client to PRISM 4 and advance to using MEF alone instead of Unity.
While many argue that MEF isn’t yet a full DI framework, it still provides an easy way to enable application extensibility in your projects.
One of the tasks that I had while upgrading the client to PRISM 4, is to keep supporting type registration in runtime, something in the sort of the following -
Code Snippet
- public interface IFoo
- {
- }
-
- [Export(typeof(IFoo))]
- public class Foo : IFoo
- {
- }
-
- catalog.Register<Bar>();
The built-in TypeCatalog that comes with MEF requires you to specify the types in the constructor and there is no support for registrations in runtime for the same catalog.
In order to support this feature, I could simply add a new TypeCatalog for every registration request in runtime with the desired type, but that seemed to be kind of wasteful.
MEF does support catalog changes in runtime, you need to implement ‘INotifyComposablePartCatalogChanged’.
The solution
I implemented a type catalog that supports registrations in runtime, here is the core implementation -
Code Snippet
- public void Register(IEnumerable<Type> types)
- {
- if (types != null)
- {
- List<ComposablePartDefinition> addedParts = new List<ComposablePartDefinition>();
-
- foreach (Type type in types)
- {
- ComposablePartDefinition part = AttributedModelServices.CreatePartDefinition(type, null);
-
- addedParts.Add(part);
- }
-
- using (var atomicComposition = new AtomicComposition())
- {
- OnChanging(new ComposablePartCatalogChangeEventArgs(addedParts, EmptyPartDefinitions, atomicComposition));
-
- _lock.EnterWriteLock();
- try
- {
- foreach (var addedPart in addedParts)
- {
- _parts.Add(addedPart);
- }
- }
- finally
- {
- _lock.ExitWriteLock();
- }
-
- atomicComposition.Complete();
- }
-
- OnChanged(new ComposablePartCatalogChangeEventArgs(addedParts, EmptyPartDefinitions, null));
- }
- }
If I need to register known types in runtime, I can just do the following -
Code Snippet
- RuntimeTypeCatalog catalog = new RuntimeTypeCatalog();
-
- CompositionContainer container = new CompositionContainer(catalog);
-
- catalog.Register<Bar>();
- catalog.Register<Foo>();
Feel free to download the full source code and see it in action.
If you have a DateTime and you would like to get the localized name of the day according to the current culture, you can just do the following -
myDateTime.ToString(“ddd”);
I had a different scenario though, I had an object with a property of DayOfWeek enum which represents week days.
I needed to display just that property in my UI as a localized string.
In this case, I don’t have a DateTime so I can’t use its culture-based string formatting, so I can’t use the approach written above.
I could obviously generate a DateTime that is of such a day and use the that approach , but that seemed quite wasteful.
Well, fear not, there is a way to do that -
You can get the DateTimeFormatInfo in your current culture (be that the CurrentCulture or the CurrentUICulture), and retrieve the day name straight from there.
Code Snippet
DayOfWeek day = DayOfWeek.Monday;
System.Globalization.CultureInfo cultureInfo = System.Threading.Thread.CurrentThread.CurrentCulture;
string dayOfWeekLocalized = cultureInfo.DateTimeFormat.DayNames[(int)day];
Update 26/09/2011 - There is an issue with the control where the entire tree is loaded, which may affect performance and memory allocation when working with many items. Unfortunately, I don’t think I would be able to fix that any time soon.
A few years back, I built a WPF control that I decided to share here now.
The control is called ComboView – A ComboBox showing a TreeView inside to display hierarchical data (you can use it for flat data if you need its features though).
The control provides some really nice built-in features that you can use.
The control uses another control that I had to write, called ‘ExtendedTreeView’. This control inherits from TreeView and adds some features on top of that.
Another thing, I used the ‘Reveal’ control provided by Bag’o’Tricks, it has some very cool stuff, worth a look.
Following is a common mode that you can use it for -
In order to see all the options and features, feel free to download the code with the showcases here – Zuker.WpfSamples.zip
Known Limitations:
- If you wish to bind to the SelectedViewItems or SelectedViewValues (Supports Two-Way), the source property must be of type ‘ObservableCollection<object>’
- If you wish to use SelectedViewValue / SelectedViewValues, you should set SyncSelectedViewValues to true.
- If you set selection in code – items or values, the SelectedViewItems property of the ComboView will not necessarily include these items right away.
- This is because of the true nature of WPF’s TreeView, I may have to expand the items internally
- If you’re dependent on that in the next line, put this logic in Dispatcher.BeginInvoke, it should be ready there.
- Since there were some patches along the way, and features that were added at a later stage, the code can be organized better
One of the core components in WCF Contrib is the ‘ClientChannel’ which handles the client side proxy creation and management, allowing you to easily call services, with the addition of environment support, using using, and comprehensive behaviors extensions model.
Currently, the built-in Client Channels can be instantiated with a configuration name which it loads the ChannelFactory with.
A common question is, how can you use the Client Channel if you like to instantiate the ChannelFactory in code.
The way to do that is to inherit from ClientChannel and override ‘CreateChannelFactoryCore’ and just return the ChannelFactory of your wish.
A more general solution, one that I recommend in every company that wants to use WCF Contrib, is to write your own base Client Channel classes to be used everywhere in your code.
This approach gives you a singular point where you can control how every Client Channel behaves and plug-in default behavior extensions.
Following is an example of such base classes. This example allows the developer to pass in a ChannelFactory to be used, that way, we enable the scenario of using a Channel Factory through code.
Code Snippet
public class MyClientChannel<T> : MyClientChannel<MyClientChannel<T>, T>
where T : class
{
public MyClientChannel() { }
public MyClientChannel(ChannelManageOptions manageOptions)
: base(manageOptions) { }
public MyClientChannel(ChannelFactory channelFactory)
: base(channelFactory) { }
public MyClientChannel(ChannelFactory channelFactory, ChannelManageOptions manageOptions)
: base(channelFactory, manageOptions) { }
}
public class MyClientChannel<TInstance, T> : ClientChannel<TInstance, T>
where T : class
where TInstance : ClientChannel<T>, new()
{
private ChannelFactory _factory;
public MyClientChannel()
{
OnInitialize(null);
}
public MyClientChannel(ChannelManageOptions manageOptions)
: base(manageOptions)
{
OnInitialize(null);
}
public MyClientChannel(ChannelFactory channelFactory)
{
OnInitialize(channelFactory);
}
public MyClientChannel(ChannelFactory channelFactory, ChannelManageOptions manageOptions)
: base(manageOptions)
{
OnInitialize(channelFactory);
}
void OnInitialize(ChannelFactory channelFactory)
{
//You can decide to disable factory caching if you provide it with a factory which is cached already
//CacheChannelFactory = (channelFactory != null);
_factory = channelFactory;
}
protected override ChannelFactory CreateChannelFactoryCore(string endpointName)
{
if (_factory == null)
{
//If the factory wasn't provided from outside, just call the base which tries to load it from the configuration
_factory = base.CreateChannelFactoryCore(endpointName);
}
return _factory;
}
}
Then, you can use it as follows -
Code Snippet
ChannelFactory<IService> myFactory = new ChannelFactory<IService>(
new NetTcpBinding(), new EndpointAddress("net.tcp://localhost:11000/MyService"));
using (MyClientChannel<IService> myClientChannel = new MyClientChannel<IService>(myFactory))
{
myClientChannel.Channel.Do(null);
}
I’ve been reading about StreamInsight lately, there’s a lot of buzz around it nowadays.
StreamInsight is mainly a data processing engine which has great performance and latency achievements, as well as massive throughput handling capabilities.
It generally targets systems which need to handle events in massive concurrency or in cases where short latency is needed for resolving the information results.
Let’s look at High Level Architecture -

The architecture resembles BizTalk to say the truth, and is common for such processing engines.
The main terms that you need to be familiar with -
- Event – An event can be any .NET class which represents an occurrence that should be processed by the processing engine. An event can have different shapes to describe the specific scenario.
- Event Sources – Any given source for inputting events into the processing engine. You build the input adapters yourself so you can implement whatever you wish to do with any given source.
For example, you may have a source which publishes events via WCF Service, Push / Polling style, Feeds, Database, etc. - Input Adapters – You implement input adapters as you need. The role of the input adapter is to get events from sources and push it over to the processing engine.
- Streams – The input adapters create an event stream that you can query against to extract any desired information.
- Complex Event Processing (CEP) Engine – The processing engine gets events from the input adapters, and handles the events altogether.
- Query – You create and define queries over input streams to retrieve any information you like.
- Output Adapters – Once you define the input streams and the desired query, you need to do something with the results. The processing engine distributes the proper results to your predefined output adapters where you can do anything you like.
- Event Targets – The target components to which you want to send the results to. For example, database, SharePoint, applications, logging, etc.
To get a notion of the order of things, let’s look at the following scenario -
You have a system which monitors a very busy high-way road and publishes events when every car passes by a certain point.
Let’s assume a new requirement is being presented - write an analytic processing system on top of that.
For example, let’s assume we need to extract the daily average amount of black cars that drive through the road.
This is a classic example for using StreamInsight.
Our first step would be to create the input adapter to get the events when a car passes by and push it over to the processing engine.
Then, we will define the query that interests us. You do that using LINQ. In this example I would query all the black cars that passed on a daily basis and get the average amount.
Afterwards, I will connect everything to my output adapter which persists the processed results into my database.
Finally, I can view the results on any given application since I have it already persisted.
General Pros -
- Great Performance and Scale-Up – This product is written in native C++ and does great work regarding performance and resource allocations. Furthermore, it knows how to scale-up. It uses more resources if available and take advantage of multi-core environments.
- Good architecture – Such architecture which consists of Input/Output and query models enables good and clean separation of things.
- Great product for dealing with massive concurrent events or short latency requirements
General Cons -
- Customization and External Code Support – The query model generates XML configuration which the processing engine can execute in its unmanaged code environment. This means that the code is executed in their environment. Such thing does enable very good performance on the one hand, but once you need to customize it or call external infrastructures, it becomes a more difficult task, especially if you don’t wish to affect the performance to the worse.
- Scale-Out – Currently, the processing engine is designed to work in-memory in one process. This means it doesn’t scale-out by design. You could perhaps write your own solution for that, but doesn’t come out-of-the-box.
There’s much more that you can learn deeper, such as event shapes, windowing, liveliness, CTI, configuration, deployment, testing, debugging, etc.
After six months as a senior consultant and architect at Sela, I have decided to take on a new venture.
Myself and some other great guys are starting a new company, named CodeValue.
The company’s main focus is developing products for developers and ALM. We already have a product at heart, which we are really excited about, and some other very cool ideas.
Furthermore, I don’t intend to stop providing consultations and training, it’s a part of me.
As a company, the purpose is to make things simpler and better for you, the developers, and we will continue to implement projects in the software industry and help bring things to life.
I had a great time during my stay at Sela. I participated as part of the experts group which consists of highly skilled architects and consultants.
Throughout my stay, a relative short one, I had done some really nice things, such as co-authored the WCF 4.0 MOC, passed lectures, consultations, and had the chance of working in highly advanced technology development groups.
I really enjoyed working at Sela, and I’d like to thank the people for giving me the chance to be a part of it – Caro Segal, Dudu Bassa, Ishai Ram.
This doesn’t mean goodbye. The goal is to join hands and work together in the future.
In continuation of the previous posts -
WPF – Editing Mode with Save and Cancel Capability
WPF – Editing Mode with Save and Cancel Capability – Dynamic ViewModelProxy
In this post I will demonstrate an elegant and simple solution that you can use regarding the second option presented in the first post series (cloning via serialization).
The Use-Case
Often, in more advanced scenarios, you need to duplicate your object for a different view. (read the first post for more detail)
A commonly used technique is using serialization to clone the object. Unfortunately, in many times, our view models aren’t cloneable easily in their nature by using serialization, especially when we use PRISM within our view models. When using PRISM, your view models may contain references to all sorts of CAL services for example, which are usually non-serializable.
The common approach for dealing with this is using serialization events. You can set the fields not be serialized (or simply set them to null before serializing) and set their values after deserialization is complete.
You need to design your object to fit such cloning technique. For example, where would you register/instantiate your commands? constructor alone is no good due to the fact the we need to support duplication via serialization.
What I have to offer is..
- ViewModelBase – My ViewModelBase provides a method that you can override - InitializeCore(bool deserializing)
- This method occurs only once!
- If the object is being instantiated normally – part of the constructor
- If the object is being serialized – after deserialization completes
- This method provides easy access for implementing things needed either in cases of instantiation or serialization
One more thing..
I mentioned this above – in PRISM (and other cases), your view models are usually not easy to duplicate, look at the following example -
Note: The code here and in my samples are using the BinaryFormatter.
Code Snippet
public class MyViewModel : ViewModelBase
{
IEventAggregator _eventAggregator;
IUnityContainer _container;
public MyViewModel(IUnityContainer container)
{
_container = container;
_eventAggregator = _container.Resolve<IEventAggregator>();
//Use the event aggregator to subscribe to events..
}
}
Currently, MyViewModel is not serialiable.
In order to make it serializable, I need to decorate my class with the Serializable attribute, but that is not enough.
The serialization will fail because the fields _eventAggregator and _container are not serializable too.
In order to make the serialization work, here is what I need to do -
Code Snippet
[Serializable]
public class MyViewModel : ViewModelBase
{
[NonSerialized]
IEventAggregator _eventAggregator;
[NonSerialized]
IUnityContainer _container;
public MyViewModel(IUnityContainer container)
{
_container = container;
_eventAggregator = _container.Resolve<IEventAggregator>();
//Use the event aggregator to subscribe to events..
}
}
2 things have been made – 1) I set my class to be serializable 2) Marked the fields to not participate in the serialization process.
Is that all? Well, no.
The serialization and deserialization back will work fine and I will have a duplicate object. However, the state of the duplicate object would be incomplete – the _eventAggregator and _container would be nulls and no processing had been done.
Now what? well, in order to make all things work properly, I would have to encapsulate the duplication in one method (be that in my view model or somewhere else) to do the following -
Serialize the view model, call an exposed method to complete operation, return the duplicate.
For example -
Code Snippet
[Serializable]
public class MyViewModel : ViewModelBase
{
[NonSerialized]
IEventAggregator _eventAggregator;
[NonSerialized]
IUnityContainer _container;
public MyViewModel(IUnityContainer container)
{
LoadState(container);
}
public void LoadState(IUnityContainer container)
{
_container = container;
_eventAggregator = _container.Resolve<IEventAggregator>();
//Use the event aggregator to subscribe to events..
}
public MyViewModel Duplicate()
{
MyViewModel other = Helpers.CloneBySerializing(this);
other.LoadState(_container);
return other;
}
}
This is quite fine and gives us a neat solution.
My goal was to make such cases simpler though, since it is quite common in PRISM-based business applications.
Here is the solution
I built a nice wrapping on top of the binary serialization that you can use for such cases. (you can switch the actual serialization provider as you may need)
You can instruct it to serialize fields by ref.
Furthermore, it supports the entire object graph. If your view model contains other view models which have such decorated fields, it will process them as well.
This means, that upon serialization, it will set null to these fields and set their value back both in the duplicate and the original object.
So, using that, my view model looks as follows - (note the use of the InitializeCore I mentioned in the beginning of the post)
Code Snippet
[Serializable]
public class MyViewModel : ViewModelBase
{
[NonSerialized, SerializeByRef]
IEventAggregator _eventAggregator;
[NonSerialized, SerializeByRef]
IUnityContainer _container;
public MyViewModel(IUnityContainer container)
{
_container = container;
_eventAggregator = _container.Resolve<IEventAggregator>();
//need to call it once more because in the base ctor the fields are null
InitializeCore(false);
}
protected override void InitializeCore(bool deserializing)
{
if (_eventAggregator != null)
{
//Use the event aggregator to subscribe to events..
}
}
}
As you can see, I no longer need to worry about state preserving. I simply tag the fields I need to be set as references and do what I need in the InitializeCore implementation which occurs at the constructor or after deserialization when the fields already have their by-ref values.
While in such a simple case it is hard to see the benefit, when it comes to more complicated classes with deeper object graphs, it becomes much easier using this approach.
So.. how do you get the actual duplicate?
You need to call my wrapper in order to generate the duplicate. the internal implementation uses the BinaryFormatter but you can change that to NetDataContractSerializer/DataContractSerializer/XmlSerializer if you need.
Code Snippet
MyViewModel other = ObjectProducer.CloneByBinarySerialize(myViewModel);
Important Note – this serialization technique goes through the entire object graph, so it is advisable to use that in scenarios where you need to serialize a single object at a certain given time. (in this example, when the user edits an employee, the performance hit isn’t an issue for the benefit of using that)
You can download the source here - Zuker.WpfSamples.zip. (Edit State Preserve – EditWithCloneSerialize)
The sample shows a case of a really simple view model, but you can go ahead and try it with the example shown here, with the use of ‘SerializeByRef’.
Update 29/07: The project was updated, there was a minor bug in the object changed notifier.
In continuation of a previous post -
WPF – Editing Mode with Save and Cancel Capability
In this post I will demonstrate an elegant and simple solution that you can utilize regarding the first option presented in the previous post.
The Use-Case
If you want to open an editable view over an existing read-only view with cancel capability, you usually wish you could use the same ViewModel instance as the DataContext.
However, this means that changes are reflected in the read-only view, plus, how would you implement the cancel operation?
The following solution demonstrates a dynamic proxy that I had written that you can use to provide elegant solution in cases where your ViewModel is simple.
By ‘simple’ I mean the ViewModel contains a set of self-contained properties (their setters don’t affect anything else) and that there are no commands needed for the editable view.
The common approach for such simple cases is defining the bindings with UpdateSourceTrigger set to ‘Explicit’.
My solution is simpler, it doesn’t require you to do that, thus you need not update the bindings upon save and such.
Moreover, my solution still provides a way to support IDataErrorInfo on the ViewModel!
The right pane contains the read-only view:
| When clicking Edit, a dialog is shown:
|
Let’s see the code
When the user clicks ‘Edit’, the code opens the dialog with the DataContext set as follows -
Code Snippet
var proxy = new ViewModelProxy<EmployeeViewModel>(emp);
editView.DataContext = proxy;
When the user chooses Save or Cancel in the dialog, the following code merges the changes into the actual EmployeeViewModel -
Code Snippet
bool? result = editView.ShowDialog();
if (result.GetValueOrDefault())
{
proxy.AcceptChanges();
}
That is all that is needed! Nothing else!
The proxy has another method - ‘RejectChanges’ if you need to reject the changes and go back to the state of the original EmployeeViewModel.
How is the magic done?
I implemented the ViewModelProxy using the DynamicObject that comes with .NET 4.0, sweet.
This can be done in previous .NET framework versions too. It would require more code though, you could implement a dynamic property bag with a type descriptor.
The ViewModelProxy performs mainly the following parts -
- When a property is set on it – it stores it into a local dictionary and notifies upon property changed
- When a property is requested from it – returns the value from the local dictionary if present, or from the source ViewModel otherwise.
- AcceptChanges applies the local dictionary values to the source ViewModel
- RejectChanges clears the local dictionary and notifies upon property changes.
- I mentioned it above, my solution supports IDataErrorInfo, make sure to check out the sample
You can download the source here - Zuker.WpfSamples.zip.
In the next post I will demonstrate another infrastructure I had implemented that you can use for more advanced scenarios.
More Posts
Next page »