Two simple tips for working with LINQ and IEnumerable<T>

by Alex Meyer-Gleaves 5 April 2012 - 2:23 AM

Meet the test subject

Let’s create a simple class that returns the numbers from 1 to 100.

public class Loopy
{
    public int Enumerations { get; private set; }
    
    public IEnumerable<int> GetSome()
    {
        foreach (int number in Enumerable.Range(1, 100))
        {
            Enumerations++;
            yield return number;
        }
    }
}

We use Enumerable.Range to grab the numbers from 1 to 100 and loop through them with a simple foreach loop. Before returning the value to the method caller we increment a counter to note the number of enumerations requested. Because we are lazy and don’t like writing extra classes, we get the compiler to build the enumerator for returning values using the sweet yield return syntax.

Use Any() instead of Count() to check for non empty return values

In the unit test below we confirm that checking Count() for a value greater than zero causes the entire list of numbers to be enumerated even though we only care if more than zero items are present. In this simple example we are not going to notice the extra cost, but in real production code that is not always the case. The bigger the number of items returned the worse the situation gets.

[Test]
public void EnumerationsUsingCount()
{
    Loopy loopy = new Loopy();

    bool gotSome = loopy.GetSome().Count() > 0;

    Assert.That(gotSome, Is.True);
    Assert.That(loopy.Enumerations, Is.EqualTo(100));
}

The next unit test confirms that using the Any() method will cause the enumeration to stop after the first value has been returned. It doesn’t matter how many items there are to potentially enumerate, the enumeration will always stop after the first item is received.

[Test]
public void EnumerationsUsingAny()
{
    Loopy loopy = new Loopy();

    bool gotSome = loopy.GetSome().Any();

    Assert.That(gotSome, Is.True);
    Assert.That(loopy.Enumerations, Is.EqualTo(1));
}

Use Enumerable.Empty<T> and never return null

When exposing something as IEnumerable<T> returning a null value is simply rude. If the caller is attempting to enumerate the return value without checking for null first they will receive an exception and get angry. Having to check for null return values ruins the nice syntax you get from the LINQ extension methods such as Count() and Any().

It means you have to do this:

IEnumerable<int> numbers = loopy.GetSome();
bool gotSome = numbers != null && numbers.Any();

Instead of this:

bool gotSome = loopy.GetSome().Any();

To return an empty enumerable of something, use the Enumerable.Empty<T> method. It will return an enumerator of the specified type that does not return any items when enumerated.

It’s time to add a couple more methods to our Loopy class. We will add one method that is bad and returns null, and another that is good and returns Enumerable.Empty<int>. Yes, everything is black and white to me here.

public IEnumerable<int> GetEmptyBad()
{
    return null;
}

public IEnumerable<int> GetEmptyGood()
{
    return Enumerable.Empty<int>();
}

Now that we have a good and bad example let’s write the first unit test. This one shows that attempting to enumerate the null return value using the Any() method causes an exception to be thrown. You don’t need null to indicate that a list is empty when an empty list does that just fine.

[Test]
public void EnumeratingNullIsBad()
{
    Loopy loopy = new Loopy();

    Assert.Throws<ArgumentNullException>(() => loopy.GetEmptyBad().Any());
}

Finally, here is our good method being happily enumerated without a care in the world.

[Test]
public void EnumeratingEmptyIsGood()
{
    Loopy loopy = new Loopy();

    Assert.DoesNotThrow(() => loopy.GetEmptyGood().Any());
}

Two simple tips to remember. One is good for performance, and the other is good for your fellow developers.

Tags: ,

Random

Worst validation message ever

by Alex Meyer-Gleaves 29 March 2012 - 11:43 PM

I was testing what I hoped (but doubted) would be a non-breaking change to a web service contract and got this doozy of a validation message from svcutil.exe (Microsoft Service Model Metadata Tool). The person that wrote this validation message clearly should have gone into the legal profession, because it reads more like legalise from an EULA than something a sane person is meant to understand:

Validation Error: Wildcard '##any' allows element ‘http://www.acme.com/Service/Foo:data’, and causes the content model to become ambiguous. A content model must be formed such that during validation of an element information item sequence, the particle contained directly, indirectly or implicitly therein with which to attempt to validate each item in the sequence in turn can be uniquely determined without examining the content or attributes of that item, and without any information about the items in the remainder of the sequence.

If you read it a couple of times it actually starts to make sense, but there is certainly a lot of room for improvement in readability.

Tags:

Web Services | Random

Autofac ASP.NET Web API (Beta) Integration

by Alex Meyer-Gleaves 8 March 2012 - 8:23 AM

With the beta release of ASP.NET MVC 4 and the ASP.NET Web API being released a few weeks ago, I decided it was about time to have a look at what the integration story would like for Autofac. The package is available for download on NuGet.

Install-Package Autofac.WebApi

While building the preview of the Web API integration I had the following goals in mind:

  • Ensure that it would work alongside the MVC integration without issues such as naming conflicts.
  • Support both the web hosting and self hosting scenarios in a single assembly.
  • Avoid taking dependencies on the System.Web.Http.SelfHost and System.Web.Http.WebHost assemblies (to help achieve the goal above).
  • Minimize the amount of configuration required to get up and running.
  • Provide a lifetime scope around each call to an API controller so that it and its dependencies are automatically disposed at the end of the call.

I had some concerns about how easy this would be given the two different modes of hosting that are supported. When self hosting the entry point is a WCF service, and when hosting in ASP.NET the entry point is a HTTP handler. My concern was that wrapping each call to the API controller in an Autofac lifetime scope would require two completely different mechanisms. Perhaps a HTTP module style implementation and WCF extension similar to those found in the existing MVC and WCF integrations. It turns out this was not the case and if you are keen on learning about the details I will discuss them after we have seen some example code (because everyone wants to see some code sooner rather than later).

Example Code

If you are hosting within ASP.NET your Application_Start method would look something like this:

protected void Application_Start()
{
    AreaRegistration.RegisterAllAreas();

    RegisterGlobalFilters(GlobalFilters.Filters);
    RegisterRoutes(RouteTable.Routes);

    BundleTable.Bundles.RegisterTemplateBundles();

    var configuration = GlobalConfiguration.Configuration;
    var builder = new ContainerBuilder();

    // Configure the container with the integration implementations.
    builder.ConfigureWebApi(configuration);

    // Register API controllers using assembly scanning.
    builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

    // Register API controller dependencies per request.
    builder.Register<ILogger>(c => new Logger()).InstancePerApiRequest();

    var container = builder.Build();

    // Set the dependency resolver implementation.
    var resolver = new AutofacWebApiDependencyResolver(container);
    configuration.ServiceResolver.SetResolver(resolver);
}

In the case of self hosting your bootstrapping code would look like this instead:

var configuration = new HttpSelfHostConfiguration("http://localhost:8080");

configuration.Routes.MapHttpRoute(
    name: "DefaultApi",
    routeTemplate: "api/{controller}/{id}",
    defaults: new {id = RouteParameter.Optional}
    );

var builder = new ContainerBuilder();

// Configure the container with the integration implementations.
builder.ConfigureWebApi(configuration);

// Register API controllers using assembly scanning.
builder.RegisterApiControllers(Assembly.GetExecutingAssembly());

// Register API controller dependencies per request.
builder.Register<ILogger>(c => new Logger()).InstancePerApiRequest();

var container = builder.Build();

// Set the dependency resolver implementation.
var resolver = new AutofacWebApiDependencyResolver(container);
configuration.ServiceResolver.SetResolver(resolver);

// Open the HTTP server and listen for requests.
using (var server = new HttpSelfHostServer(configuration))
{
    server.OpenAsync().Wait();

    Console.WriteLine("Hosting at http://localhost:8080/{controller}");
    Console.ReadLine();
}

First we are keeping a hold of the HttpConfiguration instance so that it can be provided to the ConfigureWebApi extension method on the ContainerBuilder. This is a HttpConfiguration instance when hosting in ASP.NET and a HttpSelfHostConfiguration instance when self hosting.

Next the RegisterApiControllers extension method on the ContainerBuilder is used to perform assembly scanning, looking for types that derive from IHttpController and have names with a suffix of “Controller”. This is very similar to how the MVC integration registers controllers using assembly scanning.

The InstancePerApiRequest method applied to the ILogger registration will cause it to be resolved once per API controller invocation. After the call completes it will be disposed automatically along with the API controller instance.

To avoid naming conflicts with the MVC integration the IDependencyResolver implementation has been named AutofacWebApiDependencyResolver. You provide it with the constructed container instance and then set it as the service resolver through the SetResolver method on the ServiceResolver property of the HttpConfiguration instance.

You will notice that the steps required to configure the integration are the same for both hosting scenarios. The only real difference is that the type of the HttpConfiguration instance changes depending on the hosting mode.

To register a service for lifetime scoping with both MVC controllers and Web API controllers you can apply both the InstancePerHttpRequest and InstancePerApiRequest lifetime scopes to the registration:

// Register MVC controller and API controller dependencies per request.
builder.Register(c => new Logger()).As<ILogger>()
    .InstancePerHttpRequest()
    .InstancePerApiRequest();

Implementation Details

Because of the two different hosting mechanisms a new way to manage lifetime scopes needed to found. The approach in the MVC and WCF integrations are completely different and I didn’t want both ways to be present in the Web API integration. The IHttpControllerFactory interface provided the required abstraction, though not in a perfect way.

public interface IHttpControllerFactory
{
    // Methods
    IHttpController CreateController(HttpControllerContext controllerContext, string controllerName);
    void ReleaseController(IHttpController controller);
}

This service is resolved from the dependency resolver if present, and is called by the HttpControllerDispatcher regardless of the hosting mode. The DefaultHttpControllerFactory that ships out-of-the-box handles a number of duties such as building and caching the HttpControllerDescriptor, along with various bits of exception handling. Implementing all of that did not sound like fun so I made the AutofacControllerFactory derive from the default implementation.

public class AutofacControllerFactory : DefaultHttpControllerFactory
{
    readonly ILifetimeScope _container;
    readonly ConcurrentDictionary<IHttpController, ILifetimeScope> _controllers = new ConcurrentDictionary<IHttpController, ILifetimeScope>();

    internal static readonly string ApiRequestTag = "AutofacWebRequest";

    public AutofacControllerFactory(HttpConfiguration configuration, ILifetimeScope container) : base(configuration)
    {
        if (container == null) throw new ArgumentNullException("container");
        _container = container;
    }

    public override IHttpController CreateController(HttpControllerContext controllerContext, string controllerName)
    {
        var lifetimeScope = _container.BeginLifetimeScope(ApiRequestTag);
        controllerContext.Request.Properties.Add(ApiRequestTag, lifetimeScope);

        try
        {
            var controller = base.CreateController(controllerContext, controllerName);
            if (controller != null)
                _controllers.TryAdd(controller, lifetimeScope);

            return controller;
        }
        catch (Exception)
        {
            lifetimeScope.Dispose();
            throw;
        }
    }

    public override void ReleaseController(IHttpController controller)
    {
        ILifetimeScope lifetimeScope;
        if (controller != null && _controllers.TryRemove(controller, out lifetimeScope))
            if (lifetimeScope != null)
                lifetimeScope.Dispose();
    }
}

The AutofacControllerFactory has the current ILifetimeScope injected which happens to be the root lifetime scope at the point when it is created. This will be used to create nested lifetime scopes for each controller request. When Web API asks for a controller using the CreateController method a new lifetime scope is created based on a tag that is used during the container registration process. The same tag is used in the MVC 4 integration to allow services to be registered per MVC controller and per Web API controller. The new lifetime scope is then poked into a property on the HttpRequestMessage that is accessible from the provided HttpControllerContext. It may seem a little strange at first but the creation of the controller is being delegated to the base class, which in turn looks for an IHttpControllerActivator instance in the dependency resolver, and if located will use that to create the actual controller instance. As you have properly guessed already there is an Autofac implementation of the IHttpControllerActivator that will retrieve the lifetime scope from that property and use it to create the controller instance and its dependencies in the correct lifetime scope.

public class AutofacControllerActivator : IHttpControllerActivator
{
    public IHttpController Create(HttpControllerContext controllerContext, Type controllerType)
    {
        var requestProperties = controllerContext.Request.Properties;

        if (!requestProperties.ContainsKey(AutofacControllerFactory.ApiRequestTag))
            throw GetInvalidOperationException();

        ILifetimeScope lifetimeScope = requestProperties[AutofacControllerFactory.ApiRequestTag] as ILifetimeScope;
        if (lifetimeScope == null)
            throw GetInvalidOperationException();

        return lifetimeScope.ResolveOptional(controllerType) as IHttpController;
    }

    internal static InvalidOperationException GetInvalidOperationException()
    {
        return new InvalidOperationException(
            string.Format(AutofacControllerActivatorResources.LifetimeScopeMissing,
                typeof(ILifetimeScope).FullName, typeof(HttpRequestMessage).FullName, typeof(AutofacControllerFactory).FullName));
    }
}

AutofacControllerActivator expects that if it is present in the dependency resolver, then the Autofac controller factory should be as well, and should have put the lifetime scope into the property on the HttpRequestMessage. It also expects that if the property is present that it should contain an ILifetimeScope that it can use to attempt to resolve the controller. If the controller is not found in the lifetime scope a null reference is returned and that will cause an exception to be thrown in the DefaultHttpControllerFactory when the null is assigned to the Controller property of the HttpControllerContext. Looking at the code in the current implementation of the HttpControllerDispatcher it seems that it actually expects a null being returned from the factory as a possibility even though it seems like this cannot happen.

IHttpController httpController = this._controllerFactory.CreateController(controllerContext, str);
if (httpController == null)
{
    return TaskHelpers.FromResult<HttpResponseMessage>(request.CreateResponse(HttpStatusCode.NotFound));
}

Regardless, back in the AutofacControllerFactory any exceptions are caught to ensure that the lifetime scope can be disposed immediately before re-throwing the exception. The lifetime scope is placed into a ConcurrentDictionary using the controller instance as the key, so that it can be disposed when the ReleaseController method is called after the request is complete. Unfortunately, nothing else is passed to this method so the dictionary was required to tie the controller being released back to a lifetime scope. It would be great if more context was provided between these calls so that lifetime scope could be more easily managed.

The IDependencyResolver implementation is very basic and has been named AutofacWebApiDependencyResolver to avoid naming conflicts with the existing MVC implementation. In the Web API integration it works with the root container most of the time instead of looking for a current lifetime scope. Taking the approach of always looking for an ambient lifetime scope provided to be too difficult with the dual hosting model. I don’t think this will be a problem as outside of the lifetime scope for the API controller, it appears that most services are expected to be singleton or new instances on each call.

public class AutofacWebApiDependencyResolver : IDependencyResolver
{
    readonly ILifetimeScope _container;

    public AutofacWebApiDependencyResolver(ILifetimeScope container)
    {
        if (container == null) throw new ArgumentNullException("container");
        _container = container;
    }

    public object GetService(Type serviceType)
    {
        return _container.ResolveOptional(serviceType);
    }

    public IEnumerable<object> GetServices(Type serviceType)
    {
        var enumerableServiceType = typeof(IEnumerable<>).MakeGenericType(serviceType);
        var instance = _container.Resolve(enumerableServiceType);
        return (IEnumerable<object>)instance;
    }
}

The registration extensions are also straight forward. ConfigureWebApi registers the HttpConfiguration instance making available to other services, and ensures that the Autofac controller factory and activator are registered too. Obviously, not much is going to happen if this method is not called before building your container.

public static void ConfigureWebApi(this ContainerBuilder builder, HttpConfiguration configuration)
{
    builder.RegisterInstance(configuration);
    builder.Register<IHttpControllerActivator>(c => new AutofacControllerActivator())
        .SingleInstance();
    builder.Register<IHttpControllerFactory>(c => new AutofacControllerFactory(c.Resolve<HttpConfiguration>(), c.Resolve<ILifetimeScope>()))
        .SingleInstance();
}

Scanning for controllers is implemented similar to the MVC integration except we are looking for IHttpController derived types instead.

public static IRegistrationBuilder<object, ScanningActivatorData, DynamicRegistrationStyle>
    RegisterApiControllers(this ContainerBuilder builder, params Assembly[] controllerAssemblies)
{
    return builder.RegisterAssemblyTypes(controllerAssemblies)
        .Where(t => typeof(IHttpController).IsAssignableFrom(t) && t.Name.EndsWith("Controller"));
}

Finally, and once again similar to the MVC InstancePerHttpRequest method, the InstancePerApiRequest method applies the predetermined tag to the registration so that it can be resolved within the API controller lifetime scope.

public static IRegistrationBuilder<TLimit, TActivatorData, TStyle>
    InstancePerApiRequest<TLimit, TActivatorData, TStyle>(
        this IRegistrationBuilder<TLimit, TActivatorData, TStyle> registration)
{
    if (registration == null) throw new ArgumentNullException("registration");

    return registration.InstancePerMatchingLifetimeScope(AutofacControllerFactory.ApiRequestTag);
}

That pretty much covers it. Please download the package and report any bugs on the issue tracker or if you need help post your questions on Stack Overflow using the “autofac” tag. It will be interesting to see how much things change between this Beta and the final RTW. Happing API building!

Tags:

Autofac

Autofac ASP.NET MVC 4 (Beta) Integration

by Alex Meyer-Gleaves 8 March 2012 - 8:20 AM

Following the release of Autofac 2.6.1, the Autofac MVC 4 Beta integration is now ready for downloading via NuGet. I will look into what additional features might be possible later, but the immediate priority was to make something available ensuring people could starting enjoying Autofac with MVC 4 Beta. This work is currently being done in a branch and will be merged back into the mainline once the final RTW of MVC 4 is made available.

Install-Package Autofac.Mvc4

There are no breaking changes in the API between this and the MVC 3 version of the integration so the upgrade should be fairly painless. Detailed instructions for upgrading your actual MVC 3 project can be found in the MVC 4 release notes.

Please download the package and report any bugs on the issue tracker or if you need help post your questions on Stack Overflow using the “autofac” tag. The current MVC 3 documentation on the wiki still applies and can help you get up and running if your new to the integration.

A minor change was made in the internals to allow the lifetime scope applied to a registration to be shared between MVC and the Web API (which you have no doubt now deduced is on the way too).

// Register MVC controller and API controller dependencies per request.
builder.Register(c => new Logger()).As<ILogger>()
    .InstancePerHttpRequest()
    .InstancePerApiRequest();

Technically both extension methods use the same tag for the nested lifetime scope so only one is really needed, but I like adding both because makes it obvious that the service will be scoped to the controller, regardless of it being of the MVC or Web API variety. I don’t think there is too much more to add other than to watch out for the Web API integration which will probably be available by the time you read this.

Tags:

Autofac

Private social network homepage clones

by Alex Meyer-Gleaves 8 February 2012 - 7:39 AM

Apparently if you want to be a player in the private social networking space you must adhere to a very specific formula when designing your homepage. Do not forget the company email address input at the top and the list of customers using your product at the bottom. I actually got confused momentarily as to which site I was looking at when jumping between tabs in my browser. There is nothing like standing out from the crowd.

Chatter homepage

Yammer homepage

Socialspring homepage

Tags:

Random

WSCF.blue V1.0.13 Update

by Alex Meyer-Gleaves 14 October 2011 - 6:53 AM

imageI have posted a V1.0.13 update for WSCF.blue to address a bug with the WSDL round-tripping feature. It was reported that message headers were not being round-tripped in the WSDL when fault messages existed for the same operation. I normally prefer to batch up a few bug fixes for an update build, but I can appreciate that this particular bug would get very annoying when using headers along with numerous operations.

Tags: ,

WSCF | Web Services

DateTime precision with MongoDB and the C# Driver

by Alex Meyer-Gleaves 30 September 2011 - 6:34 AM

When dealing with a database you need to be aware of any differences between how a data type is represented in your programming language and how it is stored in the database. These differences may not be noticeable at first but often surface later, when a query is not returning the expected results, or a round-tripped value is no longer exactly equal to the original value stored. The DateTime data type in .NET has a fairly high precision of 100-nanoseconds per tick and is a candidate for such issues.

Time values are measured in 100-nanosecond units called ticks, and a particular date is the number of ticks since 12:00 midnight, January 1, 0001 A.D. (C.E.) in the GregorianCalendar calendar (excluding ticks that would be added by leap seconds).

Even with SQL Server there was a considerable difference in precision prior to the introduction of the DATETIME2 data type, given that DATETIME values are stored with a precision of 3.33 milliseconds. When the required level of precision cannot find its way into the database to be round-tripped without loss a workaround needs to be created.

MongoDB stores data in a BSON format, which is a binary representation of the popular JSON format. The specification indicates that a UTC datetime value is stored as a 64-bit signed integer representing the number of milliseconds since the Unix epoch. Once again we have a mismatch in precision to the DateTime data type in .NET and need to find a workaround for this difference.

The officially supported C# driver for MongoDB provides us with some options when it comes to serializing DateTime values into the their BSON representation. Fortunately, one of these options is able to assist with the handling of precision without resorting to storing values in a different .NET data type. Lets have a look at how DateTime values are stored by working with a very simple object that has a single DateTime property called Timestamp. We will let MongoDB assign an Id value for the document.

public class Record
{
    public Guid Id { get; set; }

    public DateTime Timestamp { get; set; }
}

We will also need to write some code to insert a record so that we can have a look at the stored value. The code below creates a records collection in the test database of the local server. It then inserts a new Record document into the collection after ensuring that the collection is empty to begin with.

MongoServer server = MongoServer.Create("mongodb://localhost");
MongoDatabase database = server.GetDatabase("test");

MongoCollection<BsonDocument> records = database.GetCollection("records");
records.Drop(); // Remove any existing documents.

Record record = new Record {Timestamp = DateTime.UtcNow};
records.Insert(record);

server.Disconnect();

The result is a document with a Timestamp property that is saved using a call to ISODate. This is simply a helper function and the provided datetime will be stored as an integer value as per the BSON specification.

{ "_id" : ObjectId("4e848461d0ba9f8047c27dc7"), "Timestamp" : ISODate("2011-09-29T14:44:49.172Z") }

To gain further control of the serialization the BsonDateTimeOptionsAttribute can be applied to a DateTime property. The attribute has three properties: DateOnly, Kind and Representation. Setting the DateOnly property to true causes the time of day component to be stored as zero, and setting the Kind property allows us to store the DateTimeKind. These first two options are not going to help us with our precision issues but are obviously useful for other scenarios. It is setting the third option of Representation to BsonType.Document that will allow us to keep our tick level precision.

public class Record
{
    public Guid Id { get; set; }

    [BsonDateTimeOptions(Representation = BsonType.Document)]
    public DateTime Timestamp { get; set; }
}

After applying the attribute to our Timestamp property we can see that the value is now persisted in a format that includes the value from the Ticks property of the DateTime. This special handling of the BsonType.Document representation is being handled by the DateTimeSerializer class in the driver.

{ "_id" : ObjectId("4e848714d0ba9f8047c27dc8"), "Timestamp" : { "DateTime" : ISODate("2011-09-29T14:56:20.481Z"), "Ticks" : NumberLong("634529049804813857") } }

Instead of applying the attribute to each DateTime property it is possible to specify the default serialization behaviour by setting the DateTimeSerializationOptions.Default property.

DateTimeSerializationOptions.Defaults = new DateTimeSerializationOptions(DateTimeKind.Utc, BsonType.Document);

Now that we have the DateTime value stored with the desired precision we need to be aware of this document format when it comes time to query the values. In order to perform comparisons in a query we will compare the Ticks property of the reference DateTime to the Ticks property of the stored DateTime element.

DateTime utcNow = DateTime.UtcNow;
Record insertedRecord = new Record {Timestamp = utcNow};
records.Insert(insertedRecord);

QueryComplete query = Query.EQ("Timestamp.Ticks", utcNow.Ticks);
Record queriedRecord = records.FindOneAs<Record>(query);
Console.WriteLine(insertedRecord.Timestamp.Ticks == queriedRecord.Timestamp.Ticks);

The same technique can be used with the other comparison operators such as GT, GTE, LT and LTE. You can always encapsulate these details into a simple helper class like the sample below for the comparisons you require.

public static class DateTimeQuery
{
    public static QueryComplete EQ(string name, DateTime value)
    {
        return new QueryComplete(new BsonDocument(GetTicksName(name), value.Ticks));
    }

    public static QueryConditionList GT(string name, DateTime value)
    {
        return new QueryConditionList(GetTicksName(name)).GT(value.Ticks);
    }

    public static QueryConditionList GTE(string name, DateTime value)
    {
        return new QueryConditionList(GetTicksName(name)).GTE(value.Ticks);
    }

    public static QueryConditionList LT(string name, DateTime value)
    {
        return new QueryConditionList(GetTicksName(name)).LT(value.Ticks);
    }

    public static QueryConditionList LTE(string name, DateTime value)
    {
        return new QueryConditionList(GetTicksName(name)).LTE(value.Ticks);
    }

    static string GetTicksName(string name)
    {
        return name.EndsWith(".Ticks") ? name : name + ".Ticks";
    }
}

This lets you query directly on the property name and provide the DateTime value. No worrying about ticks.

QueryComplete query = DateTimeQuery.EQ("Timestamp", utcNow);
Record queriedRecord = records.FindOneAs<Record>(query);

The end result seems reasonable. Persisted DateTime values keep full precision and are deserialized into a DateTime value. Querying for the data becomes a little more difficult but some helpers can reduce the friction. These results were confirmed using MongoDB 2.0.0 and the MongoDB C# Driver 1.2.0.4274.

Tags:

Database

BlogEngine.NET 2.5 Upgrade

by Alex Meyer-Gleaves 31 July 2011 - 6:39 AM

I just upgraded to BlogEngine.NET 2.5 and found the process to be fairly straight forward. The upgrade instructions suggest that you start from a v2.5 installation, and then copy your existing data and settings into the fresh install. I did this and then copied some additional files that were not explicitly mentioned in the instructions. Most of these were files that I added myself to customise the blog.

  • The apple-touch-icon.png file into the root folder.
  • Extensions I added into the App_Code/Extensions folder.
  • The assembly for a custom extension I wrote into the bin folder.
  • SQL Server CE runtime files and .NET provider assembly into the bin folder.
  • JavaScript files for the jQuery lightBox plugin that I use.

After the upgrade I did get one compiler error in the SimpleDownloadCounter extension.

Compiler Error Message: CS1061: 'BlogEngine.Core.BlogSettings' does not contain a definition for 'StorageLocation' and no extension method 'StorageLocation' accepting a first argument of type 'BlogEngine.Core.BlogSettings' could be found (are you missing a using directive or an assembly reference?)

That was easily fixed by replacing the occurrence of BlogSettings.Instance.StorageLocation with BlogConfig.StorageLocation.

I moved from VistaDB to SQL Server CE during the 2.0 upgrade so that more difficult migration was already done. This time I only needed to run the SQL_CE_UpgradeFrom2.0to2.5.sql upgrade script to update my SQL Server CE database schema. I used the SQL Server Compact Toolbox add-in for Visual Studio 2010 to run the script and had no problems.

Because I run a custom theme I check for new additions to the Standard theme and add any that I feel are required into my own. A quick check of the differences showed a new item was added to the header menu in the site.master file. It adds a link to the menu that allows a user to switch between the regular and mobile version of the site when viewed on a mobile device.

<% if (Utils.IsMobile)
   { %>
<li><blog:MobileThemeSwitch runat="server" /></li>
<%
   }
%>

It seemed like a cool feature so I added the new code to my custom theme and tested the site from my iPhone to check that the new menu item was working. There were also a couple of CSS modifications that I moved over too. The last thing was to fix the titles on the Recent Comments and Recent Posts widgets. Either the space in the titles was removed during the upgrade or they were never there and I have only just noticed.

Overall, nothing too stressful. The complete list of new features in 2.5 can be found here.

Tags:

BlogEngine.NET

WSCF.blue V1.0.12 Update

by Alex Meyer-Gleaves 26 June 2011 - 5:44 AM

A V1.0.12 update release of WSCF.blue is now available for download from CodePlex. Like the previous update, this one contains a few bug fixes and one new feature. This update is made available to you courtesy of user contributed patches. A big thank you to users BartKoelman, cjberg, jamaica and MrGlover for their contributions.

Features

  • Added a new AutoSetSpecifiedPropertiesDecorator to automatically set the _Specified property to true when setter on matching property is called. Obviously this will only work when the Properties option is used.

Bug Fixes

  • Reduced the number of times menu visibility is updated in the SelectionEvents.OnChange event to help prevent OutOfMemoryException inside EnvDTE.
  • Fixed NullReferenceException in OnTypeNameChanged method of MessageContractConverter.
  • Improved validation of namespace identifiers. The original implementation only allowed ASCII letters among other deficiencies, even though C# allows most Unicode letters in identifiers.
  • Data contract generation - choice element name incorrect in generated class (http://wscfblue.codeplex.com/workitem/10624).
  • Incorrect XmlTypeAttribute for same-named types in different namespaces (http://wscfblue.codeplex.com/workitem/12733).
  • Patch for NullReferenceException on inline XSD (http://wscfblue.codeplex.com/workitem/13714).

Tags: ,

WSCF | Web Services

Windows 8 Videos

by Alex Meyer-Gleaves 2 June 2011 - 5:56 AM

It looks like the recent rumours were indeed true. The first official previews of Windows 8 are starting to surface from the D9 and Computex conferences. It appears that just like the conferences the focus is all on tablet devices.

Today, at the D9 Conference, we demonstrated the next generation of Windows, internally code-named “Windows 8,” for the first time. Windows 8 is a reimagining of Windows, from the chip to the interface. A Windows 8-based PC is really a new kind of device, one that scales from touch-only small screens through to large screens, with or without a keyboard and mouse.

If you are a Windows user looking to buy a tablet, do you buy a Windows 7 tablet now and upgrade to Windows 8 later? Running Windows 8 on the same hardware shouldn’t be a problem, but your upgrade wont be happening until sometime next year. The Android Honeycomb 3.1 update has started to roll out, and more important than just being a good update, you can actually buy a tablet and start using it right now. It’s a shame that Microsoft are still so far away from making a serious venture (back) into the tablet market.

Windows 8 sneak peak

COMPUTEX: Microsoft introduces Windows 8

Tags:

General

About the author

Alex Meyer-Gleaves I'm a Technical Architect living in Australia (that island like continent in the southern hemisphere). I love Microsoft .NET and C#. I hate early mornings, slow drivers and Lotus Notes.

Google Shared

 

Month List

Recent Posts

Recent Comments

Comment RSS

Links

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2010