TDF - TPL Dataflow Framework

by Daniel Lins Leite 30. January 2012 05:57

The Task Parallel Library (TPL) was introduced in the .NET Framework 4, providing core building blocks and algorithms for parallel computation and asynchrony. This work was centered around the System.Threading.Tasks.Task type, as well as on a few higher-level constructs. These higher-level constructs address a specific subset of common parallel patterns, e.g. Parallel.For/ForEach for delightfully parallel problems expressible as parallelized loops.

While a significant step forward in enabling developers to parallelize their applications, this work did not provide higher-level constructs necessary to tackle all parallel problems or to easily implement all parallel patterns. In particular, it did not focus on problems best expressed with agent-based models or those based on message-passing paradigms. These kinds of problems are quite prevalent in the technical computing domains of finance, biological sciences, oil & gas, and more.

For TPL Dataflow (TDF), we build upon the foundational layer provided in TPL in .NET 4. TDF is a complementary set of primitives to those primitives delivered in TPL in .NET 4, addressing additional scenarios beyond those directly and easily supported with the original APIs. TPL Dataflow utilizes tasks, concurrent collections, tuples, and other features introduced in .NET 4 to bring support for parallel dataflow-based programming into the .NET Framework. It also directly integrates with new language support for tasks and asynchrony provided by both C# and Visual Basic, and with existing language support in .NET 4 for tasks provided by F#.

for more: http://msdn.microsoft.com/en-us/devlabs/gg585582

Intereting links:

http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/08/02/tpl-dataflow-part-1.aspx

http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/12/09/tpl-dataflow-part-2.aspx

http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/12/10/tpl-dataflow-part-3.aspx

http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/12/16/tpl-dataflow-part-4.aspx

http://blogs.microsoft.co.il/blogs/bnaya/archive/2011/12/19/tpl-dataflow-idataflowblock-part-5.aspx

http://blogs.microsoft.co.il/blogs/bnaya/archive/2012/01/28/tpl-dataflow-walkthrough-part-5.aspx

http://www.microsoft.com/downloads/en/details.aspx?FamilyID=d5b3e1f8-c672-48e8-baf8-94f05b431f5c

http://www.slideshare.net/mattdotdavey/waters-north-american-trading-architecture-summit-april-2011

http://download.microsoft.com/download/1/6/1/1615555D-287C-4159-8491-8E5644C43CBA/Guide%20to%20Implementing%20Custom%20TPL%20Dataflow%20Blocks.pdf

http://blogs.msdn.com/b/pfxteam/archive/2011/11/10/10235570.aspx

 

Tags: ,

Development

Understanding SQL Server 2008 R2 Execution Plan

by Daniel Lins Leite 12. November 2011 19:25
In this post we are going to understand the SQL Server 2008 R2 Execution Plan and the differences between Clustered and Non-Clustered Index Seek and Scan, Included Columns and others index-things in SQL Server.

Read the .DOCX in the browser.



kick it on DotNetKicks.com

Tags:

Development

OWASP Top 10 in .NET

by Daniel Lins Leite 2. August 2011 22:54

Tags: ,

Development

Dependency Injection using Unity in Portuguese

by Daniel Lins Leite 25. June 2011 20:18

I am attaching a sixteen-page tutorial about Unity and IoC in Brazilian Portuguese.

Tags: , ,

Development

Using Reactive Extensions as a BackgroundWorker

by Daniel Lins Leite 27. December 2010 02:57

In this post i will show how to use the Rx (Reactive Extension) for .NET as a BackgroundWorker. This example will be a simple file enumerator in WPF. The file enumeration will run in a different thread making the application fully usable while the process runs. I will show in a step-by-step showing inclusive the commons errors when using Reactive.

The first step is to make the window. A simple window works:

The first solution is the easiest one. Just open the folder selection dialog, enumerate all the files to a list and then insert them in the ListBox.

Although this works, it freezes the window´s thread. Select a really long folder and the program stops responding to user interaction. The second problem with this solution is that all the filenames must exists at the same time in the memory. Putting a breakpoint in the enumeration line, one can easily see the memory for the process grow.

Secondary problems are that the source cannot have infinite length nor can we start to process the first item in the right moment it is ready to be processed.

Our first step will be to use the Reactive Framework (http://msdn.microsoft.com/en-us/devlabs/ee794896.aspx ). I am using the version: 1.0.2838.0.

In the .NET 4.0, the EnumerateFiles now do not return a materialized array as in the .NET 2.0. Now it returns an IEnumerable that only enumerates as you ask it to do it. This gives us the opportunity to treat it like a lazy function.

The first step in Reactive is to create an IObservable. In this case we will use the ToObservable method.

Now we are in the Observable monad and have all the power of Reactive Extensions. Debugging now, one can see that nothing happen. The ToObservable does not enumerate the list. To enumerate the list we have to use the Subscribe method:

Now we are not storing the file name in the memory, so we can have an infinite length data source, and we can start processing the first element right after it is ready. So let remove the WriteLine and put the item in the ListBox.

Running this code and you see that… the window blocks!! Hum… well, we are still running on the window thread. The observable does not necessarily runs on another thread. But now we have the power of reactive and we can easily change the thread of where the enumeration ( the observation ) will happen.

Now the observation will happen in any free thread of the pool; I do not care. Running this code we have… an exception.

As you already know, only the thread that created the control has access to it. If we take a look in one of the overrides of the Subscribe method we see that it accepts an IObserver<T>. An IObserver is a class that treats all the signals of the IObservable. In the last example we have treated the OnNext signal passing an Action to the Subscribe method.

This observer is receiving the Dispatcher that will run the action, and the action that will ran for each item. We are not interested in the OnCompleted and OnError now.

The OnNext just call the action with a low priority message. If the message is invoked with a high priority the window will not be blocked but will not be very responsive.

To help the use of this Observer, let us create an extension method for it.

Now we are ready to glue everything together.

The unique difference is the Dispatcher as the first argument. We are using our extension method here. Running now and… only part of the files appears. In my case only the first one appeared. Hum… I suspect this problem have something to do with the using statement. Let us see the type of the "files" variable.

As suspected, the files is not the observer that we passed, in fact, the observer does not have to implement the IDisposable interface; let us removed it. If we debug again we will see that it leaves the using statement before the next OnNext signal:

That is what is happening. Between the first and the second OnNext the files is disposable. Using the reflector on the Subscribe method wee se the following code:

The flag variable is the return value of the Subscribe method. It only calls OnNext on no disosabled objects. Well, let us remove the using statement to see what happens. It must list all files now.

And it is what happens! And without blocking the window thread.

If you are estranging that we do not dispose the observation is because it is not needed. The OnCompleted signal sent by the ToObservable does it for us.

Rx will try to move to the next item. If there is no next item, flag1 will be false. Since flag1 will be false and there will be no error, Rx will call the Dispose of the observation.

But there are some interesting things we can do with this disposable object. Let us make the following change in the code.

And put a Cancel button on the XAML.

If you understood everything until now, you are thinking that this will cancel the observation in the middle. And if you run and click in the "Cancel" button you will see that you are right.

I do not know you, but I do not like the boiler code that it was needed to cancel the operation. It is separated from the code that started the operation. The following code uses the Rx to put both codes near each other.

The first step is to remove the Cancel.Click handler. Then remove the Observation definition on the class. And change to the following code:

Definitely we are starting to see the power of Rx. But the world is not easy. Put a breakpoint in the cancellation Subscribe:

Run the program. Enumerate the files and hit the Cancel two times. Yes, it steps twice in the breakpoint. Why? Remember that we have not disposed the second observation. It is still alive. In this observation we are not using the ToObservable, so there is nobody to send the OnComplete signal to us.

The problem is that we only want the first signal. In classical LINQ , if we only want the first item of a collection, but return a collection ( we do not want the First() ), we want the Take(1). Rx also has the Take method, so we can use it:

Run again with the breakpoint set and you will see that it only enters in the first click of the cancel button. After this the Click event unsubscribe happen. All of this because Take calls the OnComplete signal.

Now that everything is working as expected, let us improve the code. To be honest, we do not need the ObserverOn, we can use the ToObservable directly:

In reality we do not even need our extension method. Why? We can control in which thread the observation occurs:

The enumeration will happen in another thread and will no block the window. After this it will send the file name to the control thread and the insert will happen in the right thread. Running this and you see that your window… freezes again!!

How can we be sure that there are two thread running? The Do method allows us to have side effects in the observation. We will only write the current thread to the output.

We can see that all "OT" (Observation Thread) are different from the Control Thread. And all "ST" (Subscribe Thread) are equal to the control Thread. So everything is working fine. So, why the window is blocking?

The problem is that we are filling the windows message queue with high priority messages. The ListBox modification has to do its work in low priority. Unfortunately the Rx has no way to control the priority, so we have to make our own.

One solution is using a custom observer as we did. Another solution is to create a new IScheduler. The interface is simple. We can use the reflector to copy and modify one of the schedulers. Unfortunately none of them have virtual methods.

So the first step is to implement the IScheduler interface.

The next step is to create the scheduling methods:

With this we can create an extension method to help us:

The use no, became trivial:

But there is still an improvement we can make. We can use the method TakeUntil. TakeUntil listen to an IObservable. In the first signal of other observation it stops its observation. With this we can compose the cancellation like this.

And that is all the code needed. We do not need to subscribe to events, do not have to have fields; everything is composed right here.

Tags: , ,

Development | Reactive

DirectX 10 in XNA 4.0

by Daniel Lins Leite 8. August 2010 05:57

Unfortunately, XNA has a limitation that it works only with DirectX 9. I love the framework but this limitation really annoys me. Mainly because limit the use to Shader Model 3.0. This post shows a library, called MachinaAurum.Xna.SlimDx that ends with this limitation and allows everyone to use DirectX 10 (or DirectX 11 or OpenGL) in XNA. It is NOT a rewrite of the XNA library as MonoXNA. It uses all the code base of XNA but "hacked" to use other graphical devices.

First I will try to show how to render a simple model in XNA 4.0 ( it will only work in XNA 4.0 and C# 4.0 ) and then make the code changes to render the same model in DirectX 10. The change from normal XNA to DirectX 10 has some code changes because both APIs (DirectX 9 and DirectX 10) have some differences. So, let us start!

The first step is to create a game project. Obviously a “Windows Game” because XBOX does not run DirectX 10 (and I do not have a XBOX here…)

 

 

Before the change to DirectX 10 I want to render a simple cube to the screen. So I will insert it in the Content Project.

My content type is “.dae”. For those who do not know, “.dae” is a COLLADA model. XNA by default does not have a COLLADA loader, so I am using MachinaAurum.Xna.Collada. For the time of this post the COLLADA loader is only in proof-of-concept form, but it will serve my needs here. It will load the cube and I will show that a custom loader to XNA will work in DirectX 10!! 

 

 And now I am ready to load my model in the XNA code.

DISCLAIMER #1: This is not the best way to program games. In later posts I will try to show better ways. The simplicity of the code here is just an example! Please, never write code like this. 

The first line of the method loads the cube. Then we export the absolute matrices of the model. 

In the Draw method, we have to clear the screen, enumerate all the model meshes, put the matrices in its effects and after, we draw everything. After all of this, we have:

 

A cube!!

Ok. Nothing fancy… but now let us change the graphical device from XNA DirectX 9 to DirectX 10. The first thing we have to do is add the reference to MachinaAurum.Xna.SlimDx (SlimDx is a framework to work with managed DirectX). 

And now starts the code changes… The first change is in the game main class. The XNA template, created the following code… 

I will change the base type from Game to AurumGame. 

After this I will make a small change in the constructor. The original code is… 

The important part here is the GraphicsDeviceManager class. This class creates the XNA DirectX 9 device. So let us change this class to AurumGraphicsDeviceManager. 

The second parameter is an enumerator with each graphic API that you can create.

We will choose DirectX10.

After this change we need to change the model type from Model to AurumModel.

 

The draw method has two little changes… 

The first difference is in the clear method. Now we are calling a static class that has an abstract graphic device. The same we created in the game constructor.

The second difference is in the second foreach. We changed the type from BasicEffect to dynamic. For those who do not know, dynamic is a new type in c# 4. Bing about for more information.

And that is it! We are now using DirectX 10!

DISCLAIMER #2: This code is only proof-of-concept. The shader used is ridiculous and useless. There is no way to changed it. Just a small percentage of the API is coded etc...

In future posts I will try to show the advances of this framework.

kick it on DotNetKicks.com

Tags: , ,

Development | XNA

Code Repository in Codeplex

by Daniel Lins Leite 22. May 2010 17:52

I created the code repository in Codeplex ( http://machinaaurum.codeplex.com/ ). For now, only the proxy generator and the AOP extension are in the repository.

For the AOP, i will create the constructor injection and try to optimize the injection. I want that using the AOP extension must be as fast as using the Unity normally.

For the Proxy Generator, i will organize the code and try to make a wrapper to the env.dte for TT processing.

Tags:

Development

AOP With Unity 2.0 - 3

by Daniel Lins Leite 3. May 2010 01:24

In the first post i showed a framework for Aspect-Oriented Programming ( AOP ) using only a proxy generator and a Unity 2.0. In this post i want to show the advances of the framework.

part 1 - http://www.machinaaurum.com.br/blog/post/AOP-With-Unity-20.aspx
part 2 - http://www.machinaaurum.com.br/blog/post/AOP-With-Unity-20-2.aspx

Before and After Properties

The framework now can intercept the get and the set method of a property, either before and after the execution and have some information of the original called property.

    interface IMoveOperation
    {
        int Version { get; set; }
        void Move(Account sourceAccount, Account destinationAccount, float quantity);
    }

To inject a aspect in this property, the Log aspect ( see part2 ), must implement the IPropertyInjection interface.

    class LogMethodInjection : IMethodInjection, IPropertyInjection
    {
        ILog Log { get; set; }
        string Prefix { get; set; }

        public LogMethodInjection(ILog log, string prefix)
        {
            Log = log;
            Prefix = prefix;
        }
       
        #region IMethodInjection Members

        void IMethodInjection.Before(MethodInfo methodInfo, object[] parameters)
        {
            Log.Source.TraceInformation(Prefix + " Before " + methodInfo.Name);
        }

        void IMethodInjection.After(MethodInfo methodInfo, object[] parameters)
        {
            Log.Source.TraceInformation(Prefix + " After " + methodInfo.Name);
        }

        #endregion

        #region IPropertyInjection Members

        void IPropertyInjection.BeforeGet(PropertyInfo propertyInfo)
        {
            Log.Source.TraceInformation(Prefix + " Before Get Property " + propertyInfo.Name);
        }

        void IPropertyInjection.AfterGet(PropertyInfo propertyInfo)
        {
            Log.Source.TraceInformation(Prefix + " After Get Property " + propertyInfo.Name);
        }

        void IPropertyInjection.BeforeSet(PropertyInfo propertyInfo)
        {
            Log.Source.TraceInformation(Prefix + " Before Set Property " + propertyInfo.Name);
        }

        void IPropertyInjection.AfterSet(PropertyInfo propertyInfo)
        {
            Log.Source.TraceInformation(Prefix + " After Set Property " + propertyInfo.Name);
        }

        #endregion
    }

I have to decorate the property in the concrete class.

    [Log("Class", Order = 1)]
    class MoveOperation : IMoveOperation
    {
        #region IAccountManager Members

        [Log("Method", Order = 2)]
        public void Move(Account sourceAccount, Account destinationAccount, float quantity)
        {
            sourceAccount.Quantity -= quantity;
            destinationAccount.Quantity += quantity;
        }

        [Log("Property", Order = 2)]
        public int Version { get; set; }

        #endregion
    }

And using the interface...

            {
                IMoveOperation operation = container.Resolve<IMoveOperation>();

                operation.Version = 1;

                operation.Move(a, b, 10.0f);
                operation.Move(a, b, 10.0f);
                operation.Move(a, b, 10.0f);

                Console.WriteLine(operation.Version);
            }

running this code i get the following result in the Outpu Window.

 

 

kick it on DotNetKicks.com

Tags: , , ,

Development

AOP With Unity 2.0 - 2

by Daniel Lins Leite 2. April 2010 20:07

In the first post i showed a framework for Aspect-Oriented Programming ( AOP ) using only a proxy generator and a Unity 2.0. In this post i want to show the advances of the framework.

part 1 - http://www.machinaaurum.com.br/blog/post/AOP-With-Unity-20.aspx
part 3 - http://www.machinaaurum.com.br/blog/post/AOP-With-Unity-20-3.aspx

Before and After methods

The framework now can intercept the method either before and after the execution and have some information of the original called method and its parameters.

        public void Before(MethodInfo methodInfo, object[] parameters)
        {
            Log.TraceInformation("Before " + methodInfo.Name);
        }

        public void After(MethodInfo methodInfo, object[] parameters)
        {
            Log.TraceInformation("After " + methodInfo.Name);
        }

And running i have the following log: 

Complex Aspects

Not every aspects are simple classes. Now the aspect class is being resolved by the Unity so it can have its own dependencies.

    interface ILog
    {
        TraceSource Source { get; set; }
    }

    class Log : ILog
    {
        public TraceSource Source { get; set; }

        public Log()
        {
            Source = new TraceSource("Log");
            Source.Switch.Level = SourceLevels.Verbose;
        }
    }

    class LogMethodInjection : IMethodInjection
    {
        ILog Log { get; set; }

        public LogMethodInjection(ILog log)
        {
            Log = log;
        }

        #region IMethodInjection Members

        public void Before(MethodInfo methodInfo, object[] parameters)
        {
            Log.Source.TraceInformation("Before " + methodInfo.Name);
        }

        public void After(MethodInfo methodInfo, object[] parameters)
        {
            Log.Source.TraceInformation("After " + methodInfo.Name);
        }

        #endregion
    }

Thus, the ILog interface, in the constructor, will be injected. For this the ILog must be registered in the Unity.

container.RegisterType<ILog, Log>();

Besides dependencies, the aspect constructor can have parameters that are not dependencies. For example:

    class LogMethodInjection : IMethodInjection
    {
        ILog Log { get; set; }
        string Prefix { get; set; }

        public LogMethodInjection(ILog log, string prefix)
        {
            Log = log;
            Prefix = prefix;
        }

        #region IMethodInjection Members

        public void Before(MethodInfo methodInfo, object[] parameters)
        {
            Log.Source.TraceInformation( Prefix + " Before " + methodInfo.Name);
        }

        public void After(MethodInfo methodInfo, object[] parameters)
        {
            Log.Source.TraceInformation( Prefix + " After " + methodInfo.Name);
        }

        #endregion
    }

The problem is that now, the Unity will not resolve the "prefix" parameter. For this to happen a specific injection attribute must be created. The attribute will fill the a dictionary with the name and the value of the constructor parameter.

    class LogAttribute : InjectAttribute
    {
        public LogAttribute(string prefix)
        {
            Injection = typeof(LogMethodInjection);
            Parameters.Add("prefix", prefix);
        }
    }

And the injected method must be decorated.

        [LogAttribute("Test1", Order = 1)]
        public void Move(Account sourceAccount, Account destinationAccount, float quantity)
        {
            sourceAccount.Quantity -= quantity;
            destinationAccount.Quantity += quantity;
        }

The result: 

Aspect Lifetime

The aspect class is beaing created for each instance of the target class. To see it in action, let us create this aspect.

    class CallCount : IMethodInjection
    {
        int Count = 0;

        [Dependency]
        public ILog Log { get; set; }

        #region IMethodInjection Members

        public void Before(MethodInfo methodInfo, object[] parameters)
        {
            Count++;
            Log.Source.TraceInformation(Count.ToString());
        }

        public void After(MethodInfo methodInfo, object[] parameters)
        {
            Count++;
            Log.Source.TraceInformation(Count.ToString());
        }

        #endregion
    }

Next step: decorate the injected method.

        [Inject(Order = 1, Injection = typeof(CallCount) )]
        public void Move(Account sourceAccount, Account destinationAccount, float quantity)
        {

The running code is...

            {
                IMoveOperation operation = container.Resolve<IMoveOperation>();
                operation.Move(a, b, 10.0f);
                operation.Move(a, b, 10.0f);
                operation.Move(a, b, 10.0f);
            }
            container.Resolve<ILog>().Source.TraceInformation("New Instance");
            {
                IMoveOperation operation = container.Resolve<IMoveOperation>();
                operation.Move(a, b, 20.0f);
                operation.Move(a, b, 10.0f);
                operation.Move(a, b, 10.0f);
            }

The result must be that the counter will be 6 then will come back to zero and reach 6 again... 

 Assembly and Class Aspect

The InjectAttribute can also be applied in assemblies:

[assembly: Unity2AndAop.LogAttribute("Assembly", Order = 0,  Rules = new string[]
    {
        "Unity2AndAop.(.)*"
    })]

The "Rules" property is a list of rules that will be applied to each method in the classes registration ( only registred classes by the Unity Extension will be injected ). In this example i am saying that i want that every method of every class in the Unity2Aop namespace must be injected by the Log aspect.

If both, a method and an assembly, has a aspect, both will be merged respecting the order property of both attributes. For example:

[assembly: Unity2AndAop.LogAttribute("Assembly", Order = 0,  Rules = new string[]
    {
        "Unity2AndAop.(.)*"
    })]

    [Log("Class", Order = 1, Rules = new string[]{"(.)*"})]
    class MoveOperation : IMoveOperation
    {
        #region IAccountManager Members

        [Log ( "Method", Order = 2 )]
        public void Move(Account sourceAccount, Account destinationAccount, float quantity)
        {
            sourceAccount.Quantity -= quantity;
            destinationAccount.Quantity += quantity;
        }

        #endregion   

 

And the result is... 

Download the Unity Extension and the Proxy Generator here.

kick it on DotNetKicks.com

Tags: , , ,

Development

AOP With Unity 2.0

by Daniel Lins Leite 12. March 2010 08:55

part 2 - http://www.machinaaurum.com.br/blog/post/AOP-With-Unity-20-2.aspx
part 3 - http://www.machinaaurum.com.br/blog/post/AOP-With-Unity-20-3.aspx

In this post i want to show how one can use a Inversion of Control ( IoC ) container to make some kind of Aspect-oriented programming ( AOP ). I will start with a simple example, then use Unity 2.0 to construct my types, then make a little modification to only allows administrator to run my code, then use a Proxy Generator to ease my task and finally use Unity and the Proxy generator to allow a easy AOP.

Let us start with a simple Account class.

     class Account
    {
        public Account(float quantity)
        {
            Quantity = quantity;
        }

        public float Quantity { get; set; }
    }

I want to be able to make some move operations, move some money from one account to another. So, i will create an interface and a concrete class.

    interface IMoveOperation
    {
        void Move(Account sourceAccount, Account destinationAccount, float quantity);
    }

    class MoveOperation : IMoveOperation
    {
        #region IAccountManager Members

        public void Move(Account sourceAccount, Account destinationAccount, float quantity)
        {
            sourceAccount.Quantity -= quantity;
            destinationAccount.Quantity += quantity;
        }

        #endregion
    }

And the code that use the Account class and the MoveOperation is...

    class Program
    {
        static void Main(string[] args)
        {
            Account a = new Account(100.0f);
            Account b = new Account(50.0f);

            Print(a, b);

            IMoveOperation operation = new MoveOperation();
            operation.Move(a, b, 10.0f);

            Print(a, b);

            Console.ReadKey();
        }

        private static void Print(Account a, Account b)
        {
            Console.WriteLine("A:{0}", a.Quantity);
            Console.WriteLine("B:{0}", b.Quantity);
        }
    }

Running this code give me the following result... 

Look fine... let us use the Unity to create the MoveOperation.

        static void Main(string[] args)
        {
            Account a = new Account(100.0f);
            Account b = new Account(50.0f);

            IUnityContainer container = new UnityContainer();
            container.RegisterType<IMoveOperation, MoveOperation>();

            Print(a, b);

            IMoveOperation operation = container.Resolve<IMoveOperation>();
            operation.Move(a, b, 10.0f);

            Print(a, b);

            Console.ReadKey();
        }

Let us run again to make sure that everything is still working. 

Now, i want that only the system administrator can run this MoveOperation. I will use the CurrentPrincipal of the .NET framework. For now the code does not need to run, a SecurityException will be the expected result. The secutiry will not be inserted in the MoveOperation class. I will use the Decorator Pattern that will authorize the user and call the MoveOperation class.

    class MoveOperationAuthorization : IMoveOperation
    {
        IMoveOperation Operation { get; set; }

        public MoveOperationAuthorization(IMoveOperation operation)
        {
            Operation = operation;
        }

        #region IMoveOperation Members

        public void Move(Account sourceAccount, Account destinationAccount, float quantity)
        {
            if (System.Threading.Thread.CurrentPrincipal.IsInRole("Administrator"))
            {
                Operation.Move(sourceAccount, destinationAccount, quantity);
            }
            else
            {
                throw new SecurityException();
            }
        }

        #endregion
    }

And the construction of the IMoveOperation interface will be changed in the Unity to...

            IUnityContainer container = new UnityContainer();
            container.RegisterType<IMoveOperation>( new InjectionFactory ( (u) =>
                {
                    return new MoveOperationAuthorization ( new MoveOperation() );
                }));

and the result is... 

Ok, but this solution needs a lot of infrastructure code. Every class need a decorator and the Unity configuration. I will use a Proxy Generator to generate the proxy classes and use it to make this operation a little easier.

The Proxy Generator can be downloaded here. It´s a TT to Visual Studio 2010 that generates a proxy to every interface in the project. The only thing i have to do is to insert the TT in the project and run it ( Righ-Click and "Run Custom Tool..." ). 

After the execution the TT creates an associated .CS file. This file have all the generated Proxies.

And i can use the proxy directly in the Unity configuration.

            IUnityContainer container = new UnityContainer();
            container.RegisterType<IMoveOperation>( new InjectionFactory ( (u) =>
                {
                    var proxy = new ProxyIMoveOperation(new MoveOperation());
                    proxy.Move((op, source, dest, quantity) =>
                        {
                            if (System.Threading.Thread.CurrentPrincipal.IsInRole("Administrator") == false)
                            {
                                throw new SecurityException();
                            }
                        });
                    return proxy;
                })); 

Running this code and i have the SecurityException again.

But i can not say that this code is better than the last one. I will use now a extension to the Unity (download link at the bottom) that allows a better injection of the authorization in the MoveOperation class. First i have to implement the authorization code as method injection.

    class OnlyAdministratorMethodInjection : IMethodInjection
    {
        #region IMethodInjection Members

        public void Before()
        {
            if (System.Threading.Thread.CurrentPrincipal.IsInRole("Administrator") == false)
            {
                throw new SecurityException();
            }
        }

        #endregion
    }

 

This code is totally generic. I am not saying that it will call the MoveOperation class, this authorization code can be used in any method that need to be authorized. After this i have to make a modification in the Move method.

        [Inject(Order = 1, Injection = typeof(OnlyAdministratorMethodInjection))]
        public void Move(Account sourceAccount, Account destinationAccount, float quantity)
        {

With this i am saying that the OnlyAdministratorMethodInjection will be the first method to be called before the Move method starts. And the final step is to configure the Unity Extension.

        static void Main(string[] args)
        {
            Account a = new Account(100.0f);
            Account b = new Account(50.0f);

            IUnityContainer container = new UnityContainer();
            container.AddNewExtension<UnityAopExtension>();
            container.Configure<UnityAopExtension>().RegisterType<IMoveOperation, MoveOperation>();
          
            Print(a, b);

            IMoveOperation operation = container.Resolve<ProxyIMoveOperation>();
            operation.Move(a, b, 10.0f);

            Print(a, b);

            Console.ReadKey();
        }

Now i can say that the code looks much better. Running this code we have...

Important: This is only experimental code.

MachinaAurum.Unity.Aspect.dll.7z (4.31 kb)

kick it on DotNetKicks.com

Tags: , , , , ,

Development


RecentComments

Comment RSS