Jun302010

BUG: External configuration source file in Enterprise Library 5

Published by stephane at 3:58 PM under Patterns & Partices | .NET Framework

We just started to use Enterprise Library 5 in a project here. One thing that we almost always do is takeout the EntLib configuration out of the App.config/Web.config file. I already did that several times in the past using other version of Enterprise Library with no problem.

 

What was my surprise today when I tried the same thing I always did with previous version and found that it wasn’t working anymore!

 

This is the configuration I have in my configuration editor:

Configuration Sources

 

I am configuring a Web Application Project and I'm expecting EntLib to find my entlib.config at the root of the website… Wrong!

 

The problem reside in the fact that the file path resolution logic go through a new method in v5: GetRootedCurrentConfigurationFile, and the current implementation do not handle non rooted path correctly. The problem is that the method try to check the file existence before fixing it when dealing with a non rooted path. Here is the code directly from FileConfigurationSource.cs

 

private static string GetRootedCurrentConfigurationFile(string configurationFile)
{
    if (string.IsNullOrEmpty(configurationFile))
        throw new ArgumentException(Resources.ExceptionStringNullOrEmpty, "configurationFile");

    if (!File.Exists(configurationFile))
    {
        throw new FileNotFoundException(
            string.Format(
                CultureInfo.CurrentCulture,
                Resources.ExceptionConfigurationLoadFileNotFound,
                configurationFile));
    }

    return
        Path.IsPathRooted(configurationFile)
            ? configurationFile
            : Path.Combine(AppDomain.CurrentDomain.BaseDirectory, configurationFile);
}

 

A proposed fix is already available at CodePlex but it implies to modify the source of EntLib yourself and live with a home, recompiled version of EntLib. That directly means supporting another dependency which is something I don’t want.

Here is the link to the CodePlex page:
FileConfigurationSource::GetRootedCurrentConfigurationFile throws FileNotFoundException on relative path configuration file name

 

For us, it means that we can’t use Enterprise Library Configuration Sources until this bug is fixed. But… there’s a solution to keep the benefits of having the block configuration in external files. The solution resides in .Net and have been around for a while now: configSource! What we did is use the configSource attribute to point to external files for the desired Enterprise Library sections.

 

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <configSections>
        <section name="loggingConfiguration" type="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.LoggingSettings, Microsoft.Practices.EnterpriseLibrary.Logging, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
        <section name="exceptionHandling" type="Microsoft.Practices.EnterpriseLibrary.ExceptionHandling.Configuration.ExceptionHandlingSettings, Microsoft.Practices.EnterpriseLibrary.ExceptionHandling, Version=5.0.414.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35" requirePermission="true" />
	</configSections>
	<loggingConfiguration configSource="configs\entlib-logging.config" />
	<exceptionHandling configSource="configs\entlib-exception.config" />
</configuration>

 

This way we can keep the advantage of having our configuration outside the App.config/Web.config until this bug is fixed.

 

Note: One thing to keep in mind though… You cannot tell multiple configSource to use the same file. This is why I have entlib-logging.config and entlib-exception.config declared in my web.config.



[KickIt] [Dzone] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Tags: , ,

E-mail | Permalink | Trackback | Post RSSRSS comment feed 2 Responses

Mar182010

How to use strongly-typed name with INotifyPropertyChanged

Published by eric at 8:20 AM under .NET Framework | C# | Windows | WPF

You may already have read my posts about how to use INotifyPropertyChanged in a type-safe way (here and here), but sometime you don’t want to modify all your classes to use this method. All you want is avoid the use of a magic string to define the property. Your code will be refactoring proof.

For example let say you have this property:

public string FirstName
{
    get { return _firstName; }
    set 
    {
        if (_firstName == value)
            return;
        _firstName = value;
        RaisePropertyChanged("FirstName");
    }
}

Some refactoring tool, like Resharper, will be able to change the “FirstName” string but not Visual Studio itself. The solution? Replace this string with a strong type value. How? Let’s assume we can do this:

public string FirstName
{
    get { return _firstName; }
    set 
    {
        if (_firstName == value)
            return;
        _firstName = value;
        RaisePropertyChanged(this.NameOf(p => p.FirstName));
    }
}

Notice that you must specify the “this” keyword to make it work. That is exactly What this extension method let you do:

public static class ObjectExtensions
{
    public static string NameOf<T>(this T target, Expression<Func<T, object>> propertyExpression)
    {
        MemberExpression body = null;
        if (propertyExpression.Body is UnaryExpression)
        {
            var unary = propertyExpression.Body as UnaryExpression;
            if (unary.Operand is MemberExpression)
                body = unary.Operand as MemberExpression;
        }
        else if (propertyExpression.Body is MemberExpression)
        {
            body = propertyExpression.Body as MemberExpression;
        }
        if (body == null)
            throw new ArgumentException("'propertyExpression' should be a member expression");

        // Extract the right part (after "=>")
        var vmExpression = body.Expression as ConstantExpression;

        // Extract the name of the property to raise a change on
        return body.Member.Name;
    }
}

You can event use it in your property changed handler:

private void OnPropertyChanged(object sender, PropertyChangedEventArgs args)
{
    if (args.PropertyName == this.NameOf(p => p.FirstName))
    {
        // ...
    }
}

Enjoy!



[KickIt] [Dzone] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Tags: , , ,

E-mail | Permalink | Trackback | Post RSSRSS comment feed 0 Responses

Oct022009

Using Decorator (or Wrapper) Design Patterns to add Validation to an object

Published by eric at 9:40 AM under .NET Framework | C#

Context

In most cases when someone write about the Decorator pattern it is usually related to UI stuff. The most common example is adding “decoration” to a control, for example a scroll bar. But in my humble opinion, this is not the most useful usage of Decorator. The purpose this pattern is:

“Attach additional responsibilities to an object dynamically. Decorators provide a flexible alternative to sub classing for extending functionality”

Gang of Four

If you think about it, Validation is a responsibility and so it can be added by this pattern. Of course we can add the validation to the class itself or in its base class, but how would you reuse this validation across many unrelated objects and what if you object must derive from another base class?

Solution

Decorator The solution is the Decorator pattern. With this pattern we can add new responsibility to an object without changing its internals.

For simplicity purpose we will take a simple sample that anyone can understand but the concept shown here can apply to much more complex object.

Four our sample we will take a bank account. On this account we should be able to to money deposit and withdraw. The class diagram on the right illustrate this design.

Let’s start by defining our IAccount interface

namespace Model
{
    public interface IAccount {
        string AccountNumber { get; }
        decimal Balance { get; }
        bool Active { get; }
        void Deposit(decimal amount);
        void Withdraw(decimal amount);
        void Close();
    }
}

This simple interface will be the central abstraction of the system. The goal is to never depends on concrete class and this interface in enough to add a lot of functionality around an account.

Now here the interface implementation as an Account:

using System.Diagnostics;

namespace Model
{
    [DebuggerDisplay("Account = {_accountNumber}, Balance = {_balance}")]
    public class Account : IAccount
    {
        public string AccountNumber { get; private set; }
        public decimal Balance { get; private set; }
        public bool Active { get; set; }

        internal Account(string accountNumber, decimal balance)
        {
            AccountNumber = accountNumber;
            Balance = balance;
            Active = true;
        }

        public void Deposit(decimal amount)
        {
            if (OnBeforeDeposit())
                Balance += amount;
            OnAfterDeposit();
        }

        protected virtual bool OnBeforeDeposit()
        {
            return true;
        }

        protected virtual void OnAfterDeposit() { }

        public void Withdraw(decimal amount)
        {
            if (OnBeforeWithdraw())
                Balance -= amount;
            OnAfterWithdraw();
        }

        protected virtual bool OnBeforeWithdraw()
        {
            return true;
        }

        protected virtual void OnAfterWithdraw() { }

        public void Close()
        {
            if (OnBeforeClose())
                Active = false;
            OnAfterClose();
        }

        protected virtual bool OnBeforeClose()
        {
            return true;
        }

        protected virtual void OnAfterClose() { }
    }
}

If you expand the previous block of code you will see that the implementation of IAccount is only doing business stuff. There is no other responsibility in this class than the one that is meant for. We can clearly see “Template Method” design pattern here. All “OnSomething()” method are protected and any derided class can add implementation around the process. All “Before” method can cancel the process if the return value is false. This allow extension classes to add some specific behaviour.

But one of the main thing missing in this class is “validation”. We will use the decorator pattern to do that. A decorator class is a class thst implement all the member of an abstraction and forward all the calls to an internal instance of a real implementation that abstraction. In our case the abstraction is “IAccount” so we have to make a decorator that implement that interface.

namespace Model.Decorator
{
    public abstract class AccountDecorator : IAccount
    {
        private readonly IAccount _account;

        protected IAccount Account
        {
            get { return _account; }
        }

        protected AccountDecorator(IAccount account)
        {
            _account = account;
        }

        public string AccountNumber
        {
            get { return Account.AccountNumber; }
        }

        public decimal Balance
        {
            get { return Account.Balance; }
        }

        public bool Active
        {
            get { return Account.Active; }
        }

        public virtual void Deposit(decimal amount)
        {
            Account.Deposit(amount);
        }

        public virtual void Withdraw(decimal amount)
        {
            Account.Withdraw(amount);
        }

        public virtual void Close()
        {
            Account.Close();
        }
    }
}

As you can see the constructor of the decorator takes an instance of “IAccount”. All method forward their call to that instance. This base class simplifies the process of creating concrete decorator by allowing other decorator to implement some but not all members of the interface.

Now is the time to start implementing our validation class structure. For that purpose we will create a base validation class that will be responsible of applying the validation the IAccount instance.

using System.Collections.Generic;
using Model.Decorator;

namespace Model.Validator
{
    public abstract class AccountValidatorBase : AccountDecorator
    {
        protected abstract IEnumerable<IValidation> GetValidations(decimal amount);

        protected AccountValidatorBase(IAccount account) : base(account) {}

        protected void Validate(decimal amount)
        {
            foreach (var validation in GetValidations(amount))
                if (!validation.IsValid)
                    throw validation.Exception;
        }
    }
}

This simple base class define a “GetValidations” method that all derived class must override to add a list of validation to perform on method call.

Now to implement the “Deposit” validation we have to create this class:

using System.Collections.Generic;
using Model.Validation;

namespace Model.Validator
{
    public class AccountDepositValidator : AccountValidatorBase
    {
        public AccountDepositValidator(IAccount account) : base(account) {}

        protected override IEnumerable<IValidation> GetValidations(decimal amount)
        {
            return new List<IValidation>
            {
                new AmountGreaterThanZeroValidation(amount),
                new AmountShouldHaveOnlyTwoDecimals(amount),
                new AccountMustBeActiveValidation(Account),
                new DepositAmountNotExceedMaxValidation(Account, amount)
            };
        }

        public override void Deposit(decimal amount)
        {
            Validate(amount);
            Account.Deposit(amount);
        }
    }
}

This class is responsible for creating all validation instances. The “Deposit” method is overridden to call the base “Validate” method before doing the actual deposit.

To implement those validation we need to define the “IValidation” interface.

using System;

namespace Model.Validator
{
    public interface IValidation 
    {
        bool IsValid { get; }
        Exception Exception { get; }
    }
}

Here is a sample implementation:

using System;
using Model.Validator;

namespace Model.Validation
{
    public class AmountGreaterThanZeroValidation : IValidation
    {
        public AmountGreaterThanZeroValidation(decimal amount)
        {
            Amount = amount;
        }

        public decimal Amount { get; set; }

        public bool IsValid
        {
            get { return Amount > 0; }
        }

        public Exception Exception
        {
            get { return new ArgumentOutOfRangeException("amount", Amount, "Deposit amount should be greater than 0."); }
        }
    }
}

All other validations used in “AccountDepositValidator” can be described the same way.

The last step is to create an actual “IAccount” that will implement all this stuff. To do that we will need a Bank class. A bank is responsible of creating account. It will also be responsible of decorating it with all necessary decorators.

using System;
using System.Collections.Generic;
using Model.Logging;
using Model.Validator;

namespace Model
{
    public static class Bank
    {
        static readonly SortedDictionary<string, IAccount> _accounts = new SortedDictionary<string, IAccount>();
        private static int _accountSequence = 1;

        public static IAccount CreateAccount(decimal balance)
        {
            string accountNumber = String.Format("A{0:0000}", _accountSequence++);
            IAccount account = new Account(accountNumber, balance);
            account = new AccountDepositValidator(account);
            _accounts[account.AccountNumber] = account;
            return account;
        }
    }
}

To illustrate this process in action here is a sequence diagram:

Validation with Decorator

  1. Call Bank.CreateAccount.
  2. The Bank instantiate an Account class.
  3. The Bank create an AccountDepositValidator and wrap Account with it
  4. The Bank return an instance of IAccount.
  5. Deposit is called on IAccount which is an instance of AccountDepositValidator
  6. AccountDepositValidator call Validate
  7. AccountDepositValidator call GetValidations to retrieve the list of validation to evaluate
  8. An AmountGreaterThaZeroValidation is created
  9. IsValid returns true
  10. AccountDepositValidator call base Deposit method
  11. Balance value is updated

Next

With all this in place the only thing left to do is to implement all the other validators for all method of “IAccount”.



[KickIt] [Dzone] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Tags: , ,

E-mail | Permalink | Trackback | Post RSSRSS comment feed 1 Responses

Jul272009

Type-safe INotifyPropertyChanged and derived classes

Published by eric at 7:50 AM under .NET Framework | C# | Windows | WPF

Some of you who read my previous blog post notice that this technique doesn't allow to raise “PropertyChanged” event from a derived class. This is because you can only call method of “PropertyChangedEventHandler” from the class where it is defined. Anywhere else you can only assign (+=) and unassign (-=) event handler.

One way to work around this is to add a method in your base model class that will forward the call to “PropertyChangedEventHandler”.

Here is a modified copy of the class from my previous post:

public class Model : INotifyPropertyChanged
{
    private string _data;

    public string Data
    {
        get { return _data; }
        set
        {
            if (_data == value)
                return;

            _data = value;

            // Type safe raise from base method
            RaisePropertyChanged(() => Data);
        }
    }

    protected void RaisePropertyChanged(Expression<Func<object>> expression)
    {
        PropertyChanged.Raise(expression);   
    }

    #region Implementation of INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged = null;

    #endregion
}

Now you can define a derived class and use the same method to raise a PropertyChanged event.

public class DerivedModel : Model
{
    private string _moreData;

    public string MoreData
    {
        get { return _moreData; }
        set
        {
            if (_moreData == value)
                return;

            _moreData = value;
            RaisePropertyChanged(() => MoreData);
        }
    }
}

Now with very little effort you can build a type-safe and bindable data model.

It is also useful to be able to raise many property at once. For example if have calculated properties that depends on others like in this sample class:

public class User : INotifyPropertyChanged
{
    private string _lastName;

    public string LastName
    {
        get { return _lastName; }
        set
        {
            if (_lastName == value)
                return;

            _lastName = value;
            RaisePropertyChanged(()=>LastName, ()=>FullName);
        }
    }

    private string _firstName;

    public string FirstName
    {
        get { return _firstName; }
        set
        {
            if (_firstName == value)
                return;

            _firstName = value;
            RaisePropertyChanged(() => FirstName, () => FullName);
        }
    }

    public string FullName
    {
        get { return String.Format("{0} {1}", _firstName, _lastName); }
    }

    public void RaisePropertyChanged(params Expression<Func<object>>[] expression)
    {
        PropertyChanged.Raise(expression);
    }

    #region Implementation of INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged = null;

    #endregion
}

Because a change to either “FirstName” or “LastName” should trigger a change to “FullName” you have to raise both changes from both properties. Of course you can call “RaisePropertyChanged” many times but with a simple overload you can do this. All you have to do is add this to your extensions class.

public static void Raise(this PropertyChangedEventHandler handler, params Expression<Func<object>>[] proppertyExpressions)
{
    foreach (var expression in proppertyExpressions)
        Raise(handler, expression);
}

Aside from beeing type safe, this method will give you intellisense support while you type your “RaiePropertyChanged” calls. You still have to type the right property though.



[KickIt] [Dzone] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Tags: , , ,

E-mail | Permalink | Trackback | Post RSSRSS comment feed 2 Responses

Jul222009

How to use INotifyPropertyChanged, the type-safe way (no magic string)

Published by eric at 10:43 PM under .NET Framework | C# | Windows | WPF

Implementation of the INotifyPropertyChanged interface is quite simple. There is only one event to implement. Take for example the following simple model class:

public class Model : INotifyPropertyChanged
{
    private string _data;

    public string Data
    {
        get { return _data; }
        set
        {
            if (_data == value)
                return;

            _data = value;

            // Type un-safe PropertyChanged raise 
            PropertyChanged(this, new PropertyChangedEventArgs("Data"));
        }
    }

    #region Implementation of INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged = null;

    #endregion
}

This is a pretty standard way to implement a bindable property. The problem here is the “Data” string to specify which property changed. If someone change the name of the property without changing the content of the string, the code will compile fine but won’t work. In a big application with may properties it can be hard to detect and find the problem.

The best solution is to rely on the compiler to warn us. But because the property name is a string it can’t. So let’s change that line with a type-safe one.

public class Model : INotifyPropertyChanged
{
    private string _data;

    public string Data
    {
        get { return _data; }
        set
        {
            if (_data == value)
                return;

            _data = value;

            // Type safe PropertyChanged raise
            PropertyChanged.Raise(() => Data);
        }
    }

    #region Implementation of INotifyPropertyChanged

    public event PropertyChangedEventHandler PropertyChanged = null;

    #endregion
}

What is the trick? Raise is an extension method that takes a lambda expression to specify the name of the property in a type safe way. The Raise method resolve this expression to extract the name of the property and pass it to the PropertyChanged event.

public static class PropertyChangedExtensions
{
    public static void Raise(this PropertyChangedEventHandler handler, Expression<Func<object>> propertyExpression)
    {
        if (handler != null)
        {
            // Retreive lambda body
            var body = propertyExpression.Body as MemberExpression;
            if (body == null)
                throw new ArgumentException("'propertyExpression' should be a member expression");

            // Extract the right part (after "=>")
            var vmExpression = body.Expression as ConstantExpression;
            if (vmExpression == null)
                throw new ArgumentException("'propertyExpression' body should be a constant expression");

            // Create a reference to the calling object to pass it as the sender
            LambdaExpression vmlambda = Expression.Lambda(vmExpression);
            Delegate vmFunc = vmlambda.Compile();
            object vm = vmFunc.DynamicInvoke();

            // Extract the name of the property to raise a change on
            string propertyName = body.Member.Name;
            var e = new PropertyChangedEventArgs(propertyName);
            handler(vm, e);
        }
    }
}

All you have to do is to put this extension method in your code and the jib is done. Of course at the end a string will be used to raise the PropertyChanged event but because you don’t have to type it, you don’t have to maintain it.



[KickIt] [Dzone] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Tags: , , ,

E-mail | Permalink | Trackback | Post RSSRSS comment feed 0 Responses

Mar262009

Good practice to use Dispatcher in WPF background thread

Published by eric at 10:51 AM under .NET Framework | C# | WPF

Here is a good way to use extension method in a multi threaded context. Everybody knows that when you try to update UI from any other thread than the UI you get an “InvalidOperationException” with message “The calling thread cannot access this object because a different thread owns it.”. Look at the following sample:

Let say somewhere in your code you have this

private void Button_Click(object sender, RoutedEventArgs e)
{
    // ...
    ThreadPool.QueueUserWorkItem(DoWork, this);
    // ...
}

If you implement DoWork Like this…

private static void DoWork(object state)
{
    Window1 win = (Window1) state;
    for (int i = 0; i < 100; i++)
    {
        // do some work
        win.progress1.Value = i;
    }
    win.progress1.Value = 100;
}

…you will be in trouble.

   

Because you can’t update UI from a thread other than the UI one you will get the InvalidOperationException as stated before.

The solution is to use the Dispatcher object. As from microsoft documentation:

Only the thread that the Dispatcher was created on may access the DispatcherObject directly. To access a DispatcherObject from a thread other than the thread theDispatcherObject was created on, call Invoke or BeginInvoke on the Dispatcher the DispatcherObject is associated with.

Subclasses of DispatcherObject that need to enforce thread safety can do so by calling VerifyAccess on all public methods. This guarantees the calling thread is the thread that theDispatcherObject was created on.

So our previous sample should look like this:

private static void DoWork(object state)
{
    Window1 win = (Window1) state;
    for (int i = 0; i < 100; i++)
    {
        // do some work
        win.Dispatcher.Invoke(new Action<ProgressBar, int>((p, v) => p.Value = v), win.progress1, i);
    }
    win.Dispatcher.Invoke(new Action<ProgressBar>(p => p.Value = 100), win.progress1);
}
This is a little more work but not it works. Because we don’t want to call the Dispatcher object when it’s not needed we sould do this:
private static void DoWork(object state)
{
    Window1 win = (Window1) state;
    for (int i = 0; i < 100; i++)
    {
        // do some work
        if (win.Dispatcher.CheckAccess())
            // We can call on the current thread
            win.progress1.Value = i;
        else
            // we need to call Invoke
            win.Dispatcher.Invoke(new Action<ProgressBar, int>((p, v) => p.Value = v), win.progress1, i);
    }

    if (win.Dispatcher.CheckAccess())
        // We can call on the current thread
        win.progress1.Value = 100;
    else
        // we need to call Invoke
        win.Dispatcher.Invoke(new Action<ProgressBar>(p => p.Value = 100), win.progress1);
}
Ouch! This is a lot more work. We cannot do that every time. That’s when extensions method comes handy. We can replace this whole process of choosing the right implementation with a single extension method. It will make our code more readable and more manageable.

 

 

He is the whole extension class with all possible overload for a method called Dispatch. This method will dispatch the process only if needed:

public static class DispatcherExtensions
{
    public static TResult Dispatch<TResult>(this DispatcherObject source, Func<TResult> func)
    {
        if (source.Dispatcher.CheckAccess())
            return func();

        return (TResult) source.Dispatcher.Invoke(func);
    }

    public static TResult Dispatch<T, TResult>(this T source, Func<T, TResult> func) where T : DispatcherObject
    {
        if (source.Dispatcher.CheckAccess())
            return func(source);

        return (TResult)source.Dispatcher.Invoke(func, source);
    }

    public static TResult Dispatch<TSource, T, TResult>(this TSource source, Func<TSource, T, TResult> func, T param1) where TSource : DispatcherObject
    {
        if (source.Dispatcher.CheckAccess())
            return func(source, param1);

        return (TResult)source.Dispatcher.Invoke(func, source, param1);
    }

    public static TResult Dispatch<TSource, T1, T2, TResult>(this TSource source, Func<TSource, T1, T2, TResult> func, T1 param1, T2 param2) where TSource : DispatcherObject
    {
        if (source.Dispatcher.CheckAccess())
            return func(source, param1, param2);

        return (TResult)source.Dispatcher.Invoke(func, source, param1, param2);
    }

    public static TResult Dispatch<TSource, T1, T2, T3, TResult>(this TSource source, Func<TSource, T1, T2, T3, TResult> func, T1 param1, T2 param2, T3 param3) where TSource : DispatcherObject
    {
        if (source.Dispatcher.CheckAccess())
            return func(source, param1, param2, param3);

        return (TResult)source.Dispatcher.Invoke(func, source, param1, param2, param3);
    }

    public static void Dispatch(this DispatcherObject source, Action func)
    {
        if (source.Dispatcher.CheckAccess())
            func();
        else
            source.Dispatcher.Invoke(func);
    }

    public static void Dispatch<TSource>(this TSource source, Action<TSource> func) where TSource : DispatcherObject
    {
        if (source.Dispatcher.CheckAccess())
            func(source);
        else
            source.Dispatcher.Invoke(func, source);
    }

    public static void Dispatch<TSource, T1>(this TSource source, Action<TSource, T1> func, T1 param1) where TSource : DispatcherObject
    {
        if (source.Dispatcher.CheckAccess())
            func(source, param1);
        else
            source.Dispatcher.Invoke(func, source, param1);
    }

    public static void Dispatch<TSource, T1, T2>(this TSource source, Action<TSource, T1, T2> func, T1 param1, T2 param2) where TSource : DispatcherObject
    {
        if (source.Dispatcher.CheckAccess())
            func(source, param1, param2);
        else
            source.Dispatcher.Invoke(func, source, param1, param2);
    }

    public static void Dispatch<TSource, T1, T2, T3>(this TSource source, Action<TSource, T1, T2, T3> func,
                                                     T1 param1, T2 param2, T3 param3) where TSource : DispatcherObject
    {
        if (source.Dispatcher.CheckAccess())
            func(source, param1, param2, param3);
        else
            source.Dispatcher.Invoke(func, source, param1, param2, param3);
    }
}

That seems a lot of code to write but see how it simplifies the code when you use it:

private static void DoWork(object state)
{
    Window1 win = (Window1) state;
    for (int i = 0; i < 100; i++)
    {
        // do some work
        win.progress1.Dispatch((p, v) => p.Value = v, i);
    }

    win.progress1.Dispatch(p => p.Value = 100);
}

This is almost as simple as our first implementation of DoWork. The only difference is in this version we call “Dispatch” with a lambda expression that will always be run on the UI thread.

 

 

Let me know if you find this helpful or if you think of something better.



[KickIt] [Dzone] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Tags: , , , ,

E-mail | Permalink | Trackback | Post RSSRSS comment feed 1 Responses

Mar252009

Promoting your site through a search provider

Published by david at 5:47 PM under .NET Framework | ASP.NET

The importance of search today in e-commerce websites has become one of the backbone of this industry. For that is important that your site can provide an easy way to search through it. One of those ways is using OpenSearch.

OpenSearch provides a way to expose a search provider compatible with most recent browsers such as Internet Explorer 7, 8 and Firefox 3+.

So to do that here are the basic steps:

1. Create an open search XML file that respects the following:

Value Description
ShortName (required) This is the search provider's name that is displayed in the Instant Search box when your provider is selected.
URL (required) The URL for basic search queries to your search provider. It has to be an absolute URL.
Image (optional) Pointer to a favicon file of your search provider on your Web site. This icon is displayed next to the provider name in the Instant Search box. The icon must be a valid shortcut icon file otherwise a generic icon will be used.
Suggestions URL (JSON) (optional) This is the URL where JavaScript Object Notation (JSON) suggestions can be retrieved.
Suggestions URL (XML) (optional) This is the URL where XML-based suggestions can be retrieved.
PreviewUrl (optional) URL to display results in an Accelerator Preview Window.

 

The following sample OpenSearch Description file defines the type of search services you intent to offer:

<?xml version="1.0" encoding="UTF-8"?>
<OpenSearchDescription 
       xmlns="http://a9.com/-/spec/opensearch/1.1/" xmlns:ie="http://schemas.microsoft.com/Search/2008/">
    <ShortName>My Custom Search</ShortName>
    <Image height="16" width="16" type="image/icon">http://example.com/example.ico</Image>
    <Url type="text/html" 
                template="http://example.com/search.aspx?q={searchTerms}&amp;source=IE"/>   
    <Url type="application/x-suggestions+json" 
                template="http://suggestions.example.com/search.aspx?q={searchTerms}"/>
    <Url type="application/x-suggestions+xml" 
                template="http://suggestions.example.com/search.aspx?q={searchTerms}"/>
    <ie:PreviewUrl type="text/html" 
                template="http://suggestions.example.com/search.aspx?q={searchTerms}"/>
</OpenSearchDescription> 

2. Add the appropriate tags int you <head> element to your pages

<link title="My Provider" rel="search"
type="application/opensearchdescription+xml"
href="http://www.example.com/provider.xml">

 

That’s it. Users can now have access to your provider through the dropdown.



[KickIt] [Dzone] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

Tags: ,

E-mail | Permalink | Trackback | Post RSSRSS comment feed 0 Responses