Latest news for buy viagra in canada

Average Rating: 4.8 out of 5 based on 300 user reviews.

This week I ran into wanting to use C# 4. 0 optional parameters, but wanted (my IoC tool of choice) to respect the default value specified for those optional parameters.

The Problem

In this example, we’ll be pulling a command out of the container.   The important part is the optional constructor parameter (level), and it’s default value (Level. Info).

public class LogCommand

{

    IDestination _destination;

    Level _level;

 

    public LogCommand(

        IDestination destination, Level level = Level. Info)

    {

        _destination = destination;

buy viagra in canada] 0px">        _level = level;

    }

 

    /* logging code here */

}

 

Here is your basic usage, but doesn’t work since StructureMap doesn’t know how to take advantage of the optional parameters with default values.

var container = new Container(config =>

{

    config. Scan(scanner =>

    {

        scanner. TheCallingAssembly();

        scanner. AddAllTypesOf<IDestination>();

        scanner. WithDefaultConventions();

    });

});

 

var logCommand = container. GetInstance<LogCommand>();

 

The last line results in an exception because StructureMap doesn’t know how to fill in the level parameter.

The Solution

We can solve this by adding a new convention.   One that adds information about default constructor arguments.   Here is the implementation of the convention:

public class DefaultCtorParameterConvention : IRegistrationConvention

{

    public void Process(Type type, Registry registry)

    {

        if(type. IsAbstract || type. IsEnum)

            return;

 

        var ctor = type. GetGreediestCtor();

 

        if(!ctor. HasOptionalParameters())

            return;

 

        var inst = registry. For(type). Use(type);

 

        foreach(var param in ctor. GetOptionalParameters())

            inst. Child(param. Name). Is(param. DefaultValue);

    }

}

Note: GetGreediestCtor, HasOptionalParameters, and GetOptionalParameters are extension methods.   We’ll see their implementation shortly.

The convention inherits from the IRegistrationConvention, which is how you implement new conventions in StructureMap.   It has only one method: Process.   We filter out types that are abstract, are enums, or have constructors that don’t have optional parameters.   Once we realize we have a constructor we want to deal with, we use the Child method, that sets either a property or a constructor argument (for our case, it’ll always be a constructor argument), and then we set it’s value to the parameter’s default value, as provided by the ParameterInfo object, for each optional parameter.

Minor Details

Curious about the implementation of GetGreediestCtor or the *OptionalParameters methods?  If not, skip this section.

public static bool HasOptionalParameters(

    this ConstructorInfo ctor)

{

    return ctor. GetOptionalParameters(). Any();

}

 

public static IEnumerable<ParameterInfo> GetOptionalParameters(this ConstructorInfo ctor)

{

    return ctor. GetParameters(). Where(

        param => param. Attributes

            . HasFlag(ParameterAttributes. Optional));

}

 

public static ConstructorInfo GetGreediestCtor(

    this Type target)

{

    return target. GetConstructors()

        . WithMax(ctor => ctor. GetParameters(). Length);

}

 

public static T WithMax<T>(

    this IEnumerable<T> target, Func<T, int> selector)

{

    int max = -1;

    T currentMax = default(T);

 

    foreach(var item in target)

    {

        var current = selector(item);

        if(current <= max)

            continue;

 

        max = current;

        currentMax = item;

buy viagra in canada

    }

 

    return currentMax;

}

 

 

The Usage

Here’s how to use your new convention.

var container = new Container(config =>

{

   config. Scan(scanner =>

   {

       scanner. TheCallingAssembly();

       scanner. AddAllTypesOf<IDestination>();

       scanner. WithDefaultConventions();

       scanner. Convention<DefaultCtorParameterConvention>();

   });

});

 

var logCommand = container. GetInstance<LogCommand>();

 

Now, when we pull the LogCommand out of the container, the level parameter gets defaulted to Level. Info buy viagra in canada, just like we specified in the constructor. Buy viagra in canada   sweet!

conclusion

this implementation is somewhat limiting, but the version i have in my is a little more open and configurable.   It allows you to customize the instance key/name you use when registering your type, and also allows you to do additional, non-standard registrations if you need to.

Also, this doesn’t work if you’ve selected a constructor using the SelectConstructor config API from StructureMap, I’m not sure how to tap into that facility to look for that constructor rather than the greediest.

Am I missing something?  Did something not make sense?  Leave me a note!


?? 2008-2016 Legit Express Chemist.