I think this approach will have an issue in multi-threaded use, because try getting the value and adding it is done during two different locks, meaning that it can be added twice.

The lock needs to go around the `TryGetValue` and the possible `Add`, which means using a `Func<Assembly, Type[]>` might help here

like

```CSharp

private static readonly object dictionaryLock = new object(); // no casting to IDictionary

public static void SafeAdd(Assembly assembly, Func<Assembly, Type[]> determineTypes)
{
    lock(dictionaryLock)
    {
        Type[] assemblyTypes;
        if(!dictionary.TryGetValue(assembly, out assemblyTypes))
        {
            assemblyTypes = determineTypes(assembly);
            dictionary.Add(assembly, assemblyTypes);
        }
    }
}
```

And when I think of it, since this is the `StaticAssemblyTypesDictionary` why not move the whole try / getTypes / catch logic into that class and name it `AssemblyTypesResolver` with one method `ResolveTypes(Assembly assembly)` which can then do the whole locking part, getting types part, catching part and in the end return all the resolved types after having them stored in the dictionary. This way that class has a little bit more meaning than just storing the types?

What do you think?