Archive

Archive for November, 2011

Split Windows + Web Workbench = Win

November 27th, 2011 No comments

One of the cool features of the Web Workbench from Mindscape is the ability to generate the output files. Prior to using the Web Workbench I was using .LESS{} which uses an HTTP Handler to generate the output files for LESS.

The problem with this is sometimes I would write some CSS and not realise I missed something only to find my site doesn’t display anything, then I have to figure out what I did wrong.

With the Web Workbench, and it’s ability to generate the files every time I save, makes me less error prone.

But the most efficient way of working with it I found (when writing a lot of CSS in 1 sitting) is to split my windows so the first window has where I’m writing, and the second window has the generated CSS file.

image

If I make an error on the left side:

image

I see the error on the right.

If I make a change to the left, (added a background colour) i see the change on the right.

image

This makes it really handy when applying nested rules. Such as nesting a hover rule to an anchor tag. Sometimes I forget to include the colon.

image

Maybe in the next version of the Web Bench, Mindscape can include side-by-side windows that scroll with each other Open-mouthed smile Tho it would be difficult depending on how much CSS was generated. Would still be a nice feature.

Either way, the Web Workbench is a tool that can’t be missed.

Categories: General Tags: , ,

Optional Parameters with AttributeRouting

November 27th, 2011 3 comments

I found a little trick with using Optional Parameters with AttributeRouting, by using standard optional parameters in the action.

The documentation says you can add an attributes to specify the defaults, or add ‘=value’ to the parameter name, and I guess that’s a more correct way to generate routes, but you can achieve the same affect by making the parameter optional. Like so:

[GET("videos/{?page}")]
public ActionResult Videos(int page = 1)
{
    return View("Result");
}

If I browse to the URL:

image

It uses the default value of 1.

image

Now when appending a number to the end of the URL:

image

It captures the correct value:

image

I prefer this method, the optional parameter on the action is more quickly identified, than looking at the attribute to see the defaults. (in my opinion)

Ahh AttributeRouting, how I love you.

Unit of Work with WCF and Autofac

November 6th, 2011 No comments

I’ve just spent the last few days trying to find a way to have a Unit of Work with WCF, but it seems no one has a nice clean easy solution.

The first, and the only decent solution I found was here:

http://ianfnelson.com/archives/2010/04/09/wcf-nhibernate-unit-of-work-endpoint-behavior

The problem I found with this solution is that the ICallContextInitializer as well as the EndpointBehavior is only created once. So it would seem all calls to a service would share the same Unit of Work instance.

Maybe Castle Windsor does something fancy and injects a brand new EndpointBehavior every request to a service, but for me, it seemed the ServiceBehavior, EndpointBehavior, and ICallContextInitializer were all created once.

This caused my service to resolve a different instance of IUnitOfWork to what was in the ICallContextInitializer.

Interim Solution 1

The first solution I came up with was to use Autofac to call Commit on release:

builder.RegisterType(typeof (UnitOfWork))
        .As(typeof (IUnitOfWork))
        .InstancePerLifetimeScope()
        .OnRelease(x =>
                        {
                            ((IUnitOfWork) x).Commit();
                        });

It works… Smile but it seemed like a real hack, so I kept digging.

I posted on StackOverflow & Autofac Google Group, but so far I haven’t had anyone suggest a good solution.

Solution 2

The next took a while to come up with.

Note: I don’t know if this is an appropriate solution for utilizing a Unit of Work with WCF. It works for me but if there is a better solution I would like to hear it.

I started by giving all my classes an interface called IService.

public interface IService
{
    IUnitOfWork UnitOfWork { get; set; }
}

My Service implements this interface:

public class WasteInventoryQueryService : IWasteInventoryQueryService, IService
{
    public IUnitOfWork UnitOfWork { get; set; }
    public IWasteStockRepository WasteStockRepository { get; set; }

    public WasteInventoryQueryService(IUnitOfWork unitOfWork, IWasteStockRepository wasteStockRepository)
    {
        UnitOfWork = unitOfWork;
        WasteStockRepository = wasteStockRepository;
    }

    …
}

Next I created some behaviours similar to the linked article.

Since finding that the ServiceBehavior, EndpointBehavior and ICallContextInitializer all are created once, I started at the ServiceBehavior.

I created a class called EndpointResolverServiceBehavior, it’s purpose is to inject all the endpoint behaviours I create.

public class EndpointResolverServiceBehavior : IServiceBehavior
{
    protected IEnumerable<IEndpointBehavior> EndpointBehaviors { get; set; }

    public EndpointResolverServiceBehavior(IEnumerable<IEndpointBehavior> endpointBehaviors)
    {
        EndpointBehaviors = endpointBehaviors;
    }

    #region Implementation of IServiceBehavior

    public void Validate(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
    }

    public void AddBindingParameters(ServiceDescription serviceDescription,
        ServiceHostBase serviceHostBase,
        Collection<ServiceEndpoint> endpoints,
        BindingParameterCollection bindingParameters)
    {
    }

    public void ApplyDispatchBehavior(ServiceDescription serviceDescription, ServiceHostBase serviceHostBase)
    {
        foreach (var endpoint in serviceDescription.Endpoints)
        {
            foreach (var endpointBehavior in EndpointBehaviors)
            {
                endpoint.Behaviors.Add(endpointBehavior);
            }
        }
    }

    #endregion
}

Next I created an EndpointBehavior called UnitOfWorkEndpointBehavior, it’s purpose is to add the ICallContextInitializer instance.

public class UnitOfWorkEndpointBehavior : IEndpointBehavior
{
    public void AddBindingParameters(ServiceEndpoint endpoint, BindingParameterCollection bindingParameters)
    {
    }

    public void ApplyClientBehavior(ServiceEndpoint endpoint, ClientRuntime clientRuntime)
    {
    }

    public void ApplyDispatchBehavior(ServiceEndpoint endpoint, EndpointDispatcher endpointDispatcher)
    {
        foreach (DispatchOperation operation in endpointDispatcher.DispatchRuntime.Operations)
        {
            operation.CallContextInitializers.Add(new UnitOfWorkCallContextInitializer());
        }
    }

    public void Validate(ServiceEndpoint endpoint)
    {
    }
}

And then is the ICallContextInitializer.

public class UnitOfWorkCallContextInitializer : ICallContextInitializer
{
    private PropertyInfo _userObjectInfo;
    private readonly BindingFlags _flags = BindingFlags.NonPublic | BindingFlags.Instance;

    public object BeforeInvoke(InstanceContext instanceContext, IClientChannel channel, Message message)
    {
        if (_userObjectInfo == null)
            _userObjectInfo = instanceContext.GetType()
                                                .GetProperty("UserObject", _flags);
            
        return _userObjectInfo.GetValue(instanceContext, null) as IService;
    }

    public void AfterInvoke(object correlationState)
    {
        var uow = correlationState as IService;

        if (uow != null)
            uow.UnitOfWork.Commit();
    }
}

While debugging I found out that the InstanceContext has a private property which has the current service attached to it:

image

image

(click the image for a larger view)

So I reflected the property and casted it to an IService, and return the result. When the service has been invoked, the result passed out of the ‘BeforeInvoke’ method, is passed into the ‘AfterInvoke’.

image

So basically I return the result from the BeforeInvoke which is passed into the AfterInvoke. Then I attempt to cast it to an IService again.

If the cast is successful, then I can call Commit on my UnitOfWork.

The last piece is to wire up the Behavior with Autofac.

builder.RegisterType(typeof(UnitOfWorkEndpointBehavior)).As(typeof(IEndpointBehavior));
builder.RegisterType(typeof(EndpointResolverServiceBehavior)).As(typeof(IServiceBehavior));

Container = builder.Build();

AutofacHostFactory.Container = Container;
AutofacHostFactory.HostConfigurationAction =
    host =>
    {
        host.Description.Behaviors.Add(Container.Resolve<IServiceBehavior>());
    };

And it’s done. I have a working Unit of Work, that is injected into my Service and Committed after the service has been invoked.

The only down-side I see to all of this, is that if an exception is thrown that I don’t capture, then the UoW will still be committed regardless.

If anyone has any better solutions, let me know! Smile

Categories: WCF Tags: , ,

Windows Phone, Windows Live and MSN

November 2nd, 2011 1 comment

Windows Phone 7.5 has been getting some awesome reviews, and rightly so. The thing is amazing. I really think Microsoft has begun leading the way for the mobile platform.

But I’m highly pissed off with the Windows Phone team. Why? Because to use MSN, your msn contacts must be associated with the first live account you register to the phone.

I don’t even know what to say about this, it’s so silly. I understand that it might get confusing to allow multiple Facebook accounts, multiple Windows Live accounts, etc.

But could they not allow you to choose which account MSN contacts are associated to?

When I first setup my phone I didn’t use the Windows Live account I use for MSN (my Hotmail) since it’s existed since 1997, it’s got 100′s of contacts I don’t want in my phone-book, a lot of MSN contacts exist from work, or playing online games, or from forums etc. So I used the Windows Live account that I use for MSDN. I added all my contacts and everything was great, (after I imported all my contacts from outlook into Windows Live Contacts)

I attached my Facebook account, went to People > Settings > Filter Contacts, and turned off Facebook so they do not show in my normal contacts list. This allows me to have normal phone users, but see the Facebook users on the Messaging list.

Now I want to show MSN contacts, so I load up the next Windows Live account, it loads all my contacts, but when I go to messaging, I get NOTHING. No MSN users at all.

On my second Windows Phone (yes I have two) I reformatted it, and signed it up on my Hotmail Windows Live account, and what do I see? All my MSN contacts.

Ok so the team didn’t give us the option to select which Live account we can use for MSN… So I went to download IM+

DEAD END

ATTENTION MSN/WLM users! MSN/WLM is not supported in 1.7 version of IM+ due to Microsoft Marketplace request. If you would like to continue using MSN/WLM in IM+, do not update to 1.7 version from version 1.2. We will continue working on this situation with Microsoft.

WTF… So not only can I not use MSN on my phone natively. The team has blocked anyone else from providing the feature in their own applications…

That’s not fair at all.

Microsoft should be ashamed.

So as it stands, if you don’t use your MSN account as your Windows Phone account, you can’t use MSN.

Microsoft is definitely leading the way in Mobile platform, but they massively screwed up MSN for many users.

Categories: Rant, Windows Phone 7 Tags: