score:2

Accepted answer

I think this is a good example of the dynamic factory pattern. I do this all the time. I understand your concern about exception handling but I think there is no need for this, simply because your unit tests will prevent this factory from ever throwing during production and a good unit test can explain as clearly the problem as an exception message.

But if you really want to do error checking, your LINQ query will never throw an exception. It is the ToDictionary that will throw when there is a double key. What you can do is validate the results of the LINQ query and communicate the double keys:

static GraphFactory()
{ 
    var items = (
        from type in _assembly.GetTypes()
        where type.GetInterface(typeof(IGraph).FullName) != null
        from attribute in type.GetCustomAttributes(true)
            .OfType<GraphTypeAttribute>
        select new { attribute, type }).ToArray();

    ValidateTypes(items);

    _item = items.ToDictionary(
        k => k.attribute.CustomType, e => e.type);
}

private static void ValidateTypes<T>(T[] items)
{
    var firstDoubleCustomType = (
        from item in items
        group item by item.attribute.CustomType into g
        where g.Count() > 1
        select g.Key).FirstOrDefault();

    if (firstDoubleCustomType != null)
    {
        throw new InvalidProgramException(
           "Doube: " + firstDoubleCustomType.ToString());
    }
}

Related Articles