Unity.AutoRegistration - registers only interfaces and types with the same name
-
16-06-2021 - |
Frage
Unity.AutoRegistration works fine when a type name matches an interface name, for example, TClass
and ITClass
. I want interface names go without prefix "T", like IClass
and need that IClass
to match TClass
.
But when I rename the interface, the auto-registration fails. Do I have to match the type/interface names, or is there a way to accomplish my need?
Lösung
After consulting with the author, here is the required code:
UContainer
.ConfigureAutoRegistration()
.LoadAssemblyFrom(Assembly.GetEntryAssembly().Location)
.ExcludeSystemAssemblies()
.Include(If.ImplementsITypeName, Then.Register())
.Include(
type => type.GetInterfaces().Any(i => i.Name.StartsWith("I") && i.Name.Substring(1) == type.Name.Substring(1)), Then.Register())
.Include(If.ImplementsSingleInterface, Then.Register())
.ApplyAutoRegistration();
Andere Tipps
The code for AutoRegistration has not been touched for a very long time. The TecX project on codeplex contains an enhanced configuration engine for Unity that started as a port of StructureMap's configuration. This engine also supports conventions for registration.
One of the default conventions registers the class MyService
as implementation of the interface IMyService
. It looks as simple as that:
public class ImplementsIInterfaceNameConvention : IRegistrationConvention
{
public void Process(Type type, ConfigurationBuilder builder)
{
if (!type.IsConcrete())
{
return;
}
Type pluginType = FindPluginType(type);
if (pluginType != null &&
Constructor.HasConstructors(type))
{
builder.For(pluginType).Add(type).Named(type.FullName);
}
}
private static Type FindPluginType(Type concreteType)
{
string interfaceName = "I" + concreteType.Name;
Type[] interfaces = concreteType.GetInterfaces();
return Array.Find(interfaces, t => t.Name == interfaceName);
}
}
If you need some custom naming convention it would be very easy to modify the sample above. Using that convention to configure your container would look something like this:
var builder = new ConfigurationBuilder();
builder.Scan(s =>
{
s.AssembliesFromApplicationBaseDirectory();
s.With(new MyCustomConvention());
});
var container = new UnityContainer();
container.AddExtension(builder);