#castle

Posts tagged castle

Setting a InsertedOn Field with Castle ActiveRecord

If I want a field to contain the date of insertion I’d usually have to hook into the Create method somewhere be it my repository or whatever.
With Castle ActiveRecord it’s as simple as overriding the Create() method in your Entity:

[ActiveRecord]
public class Comment : ActiveRecordBase<Comment>
{
    [PrimaryKey]
    public long Id { get; set; }
    [Property]
    public DateTime CreatedOn { get; set; }
    [Property]
    public string Message { get; set; }
    private void SetInsertionTimestamp()
    {
        CreatedOn = DateTime.Now;
    }
    public override void Create()
    {
        SetInsertionTimestamp();
        base.Create();
    }
    public override void CreateAndFlush()
    {
        SetInsertionTimestamp();
        base.CreateAndFlush();
    }
}

Read more →

How to make a LinQ2SQL DataContext IoC friendly

I’d really like to meet the guy who came up with the genius idea to call all parameters the same on the LinQ DataContext object:

image

So, when I tried to provide the connection through a named parameter with Castle Windsor I failed since the container can’t resolve what constructor to use (trying to match the key “connection”).

Thank god Microsoft didn’t seal the class so you can battle this problem by simply subclassing the construction:

public class InjectableDataContext : DataClassesDataContext
{
    public InjectableDataContext(string connectionString) 
        : base(connectionString)
    {
        
    }
}

Note that I directly subclassed my own LinQ2SQL DataContext (called DataClassesDataContext in this example).

Now I can have my configuration inject a connection string:

string myConnectionString = "DataSource...";
Component.For<DataClassesDataContext>()
    .ImplementedBy<InjectableDataContext>()
    .Parameters(Parameter.ForKey("connectionString").Eq(myConnectionString));

And the resolving code doesn’t change a bit:

var dbContext = container.Resolve<DataClassesDataContext>();

Read more →

Extensibility can equal configurability

The following code is extensible and configurable:

public class Worker
{
    private IValueCalculator valueCalculator = new DefaultValueCalculator();

    public IValueCalculator ValueCalculator     {         get { return valueCalculator; }         set { valueCalculator = value; }     }

    public decimal Work(int number)     {         return valueCalculator.Calculate(number);     } }

What happens here is that I am using the strategy pattern to implement different behaviors to keep my Worker class safe from changes to the calculator code.
Basically I’m doing dependency injection here, but I don’t inject the class through the constructor but through setter injection.

Since I am not bound to the construction phase of the object, I can easily swap IValueCalculator implementations during the worker’s lifetime without having to reconstruct the whole object.

Now, why is this extensible AND configurable?

It’s extensible because it’s easy to implement the IValueCalculator interface and supply it to a worker instance, without changing any of the plumbing around it.
If I want to change the behavior for just one call i can do that very easily:

var worker = new Worker();
var oldCalculator = worker.ValueCalculator;
worker.ValueCalculator = new AlternativeCalculator();
worker.Work(1701);
worker.ValueCalculator = oldCalculator;

But the real beauty of the whole thing is that an inversion of control container like Castle Windsor can also inject setters, so in absence of a configuration file, the default implementation from the code will be used.


But once a Windsor configuration is found you can swap the strategy classes through the configuration even without recompiling like this:

<components>
    <component 
        id="Worker"
        type="Blog_Sample.Worker, Blog_Sample" />
    <component
        id="Alternative.Calculator"
        service="Blog_Sample.IValueCalculator, Blog_Sample"
        type="Blog_Sample.AlternativeCalculator, Blog_Sample" />
</components>

If you want the default behavior just delete the Alternative.Calculator component and no setter injection will happen. If a service implementing IValueCalculator is present that one will be injected to the Worker.

Read more →