27Aug/102

Low Cost Viagra

Low cost viagra I hate every time I am working on something and I have to implement INotifyPropertyChanged.  My DRY-dey sense tingles.  Not only am I forced to not use auto-properties (1st DRY violation), low cost viagra I’m forced to fire the event in each setter (2nd DRY violation), low cost viagra and specify the name of the property that is getting set, low cost viagra inside of that property’s setter (3rd DRY violation).  That much WET (read: not-DRY), low cost viagra for something so simple leaves me a little grumpy.

Low cost viagra I’ve been on this quest before, low cost viagra to simplify this a bit, low cost viagra but it was still a little hackety, low cost viagra and limiting.

Low cost viagra This time, low cost viagra I set out to do it right.

Low cost viagra I’ll spare you most of the technical details, low cost viagra but it’s backed by Castle’s DynamicProxy project, low cost viagra and there’s some integration with StructureMap to make it super easy, low cost viagra though you don’t really have to use StructureMap if you don’t want to.  [note:  I’ll probably add more container support as I find time.  If you have a specific need, low cost viagra let me know, low cost viagra or submit a patch.]

Low cost viagra Here are the codez to show it in action:

Basics

Using it for a class with an interface

// note the attribute goes on the interface, low cost viagra not the class

[AutoNotify]

public interface IFoo

{

    string Value { get; set; }

}

 

public class Foo : IFoo

{

    public string Value { get; set; }

}

 

Using it for a class

[AutoNotify(Fire = FireOptions.OnlyOnChange)]

public class Foo

{

    // note for autonotify to work, low cost viagra the property must be virtual

    public virtual string Value { get; set; }

}

 

Low cost viagra The previous example shows how to get the event to fire only when the value is different also.  It defaults to always firing, low cost viagra whether the value changes or not.  It’s also important to note that your properties need to be virtual so the calls to the setter can be intercepted.

Dependent Properties

Low cost viagra Sometimes (usually) you’ve got calculated properties that need to fire the notified event too, low cost viagra these usually turn into WET mess as well.  We’ve got the problem solved, low cost viagra and you’ve got a few different options, low cost viagra hopefully one of them suits you.

Dependency Map – DependsOn

Low cost viagra You specify the type that defines the DependencyMap on the attribute, low cost viagra and then set up your dependencies in that type’s constructor.  This style is somewhat influenced by the FluentNHibernate API.

[AutoNotify(DependencyMap = typeof(ProjectDependency))]

public class Project

{

    public virtual string Name { get; set; }

    public virtual string[] Files { get; set; }

    public virtual int FileCount { get { return Files.Length; } }

}

 

class ProjectDependency : DependencyMap<Project>

{

    public ProjectDependency()

    {

        Property(x => x.FileCount).DependsOn(x => x.Files);

    }

}

 

Dependency Map – Updates

Low cost viagra If you’d rather express your dependency the other way around, low cost viagra that’s fine too.  The two are equivalent.

[AutoNotify(DependencyMap = typeof(ProjectDependency))]

public class Project

{

    public virtual string Name { get; set; }

    public virtual string[] Files { get; set; }

    public virtual int FileCount { get { return Files.Length; } }

}

 

class ProjectDependency : DependencyMap<Project>

{

    public ProjectDependency()

    {

        Property(x => x.Files).Updates(x => x.FileCount);

    }

}

 

Dependency Map – UpdatesWith

Low cost viagra If you want to stick with an auto-property, low cost viagra and leave the calculated property logic somewhere else, low cost viagra you can hook it in via your dependency map too.  This example, low cost viagra again, low cost viagra is equivalent to the previous two.

[AutoNotify(DependencyMap = typeof(ProjectDependency))]

public class Project

{

    public virtual string Name { get; set; }

    public virtual string[] Files { get; set; }

    public virtual int FileCount { get; set; }

}

 

class ProjectDependency : DependencyMap<Project>

{

    public ProjectDependency()

    {

        Property(x => x.Files).Updates(x => x.FileCount).With(p => p.Files.Length);

    }

}

 

DependsOn Attribute

Low cost viagra If you don’t like any of those options and are looking for something a little more simple, low cost viagra maybe you’ll like this one.  Just specify which things your property depends on in an attribute.  You lose your 100% static typing help, low cost viagra but it’s more concise.

[AutoNotify]

public class Project

{

    public virtual string Name { get; set; }

    public virtual string[] Files { get; set; }

 

    [DependsOn("Files")]

    public virtual int FileCount { get { return Files.Length; } }

}

 

Containers and otherwise

Hooking it into StructureMap

Low cost viagra There are a couple conventions you can use to hook into StructureMap.  There is the attribute convention (which is what you’re seeing above), low cost viagra and there is a generic predicate convention that you can use any predicate logic.  Below you can see the attribute one getting hooked in.

var container = new Container(config => config.Scan(scanConfig =>

{

    scanConfig.With(new AutoNotifyAttrConvention());

    scanConfig.TheCallingAssembly();

    scanConfig.WithDefaultConventions();

}));

 

var project = container.GetInstance<Project>();

Using it without StructureMap

Low cost viagra If you’re using another container, low cost viagra or no container at all, low cost viagra but want to use some other factory or something, low cost viagra you can do that too.  This example is for something with an interface.  It’s very similar to do the same for a concrete class… you just don’t instantiate the object first.  You also have an opportunity to hook into the dependent property structure here as well with the DependencyMap parameter.

var foo = new Foo();

var notifiableFoo = Notifiable.MakeForInterface(

    typeof(IFoo), low cost viagra

    foo, low cost viagra

    FireOptions.Always, low cost viagra

    new ProxyGenerator(), low cost viagra

    DependencyMap.Empty);

 

Assert.That(notifiableFoo is INotifyPropertyChanged);

 

Whew, low cost viagra done

Low cost viagra So… that’s a lot of ‘how to’, low cost viagra but hopefully it’ll be somewhat complete introduction to get you working with it.  I really don’t see much of any reason to ever implement INotifyPropertyChanged ever again (unless you are in an environment where you can’t use DynamicProxy).  It can automatically be done for you from now on.

Low cost viagra The code is up on github, low cost viagra and there is a gem up on rubygems if you’re using nu or noodle+bundler.  Fork it, low cost viagra send me a patch, low cost viagra use it, low cost viagra send feedback, low cost viagra etc.  I hope you love it!