Unity.AutoRegistrationは、タイプ名がインターフェイス名と一致する場合に正常に機能します (たとえば、TClass
and ITClass
. インターフェイス名にプレフィックス「T」を付けないようにしたいのですが、一致IClass
する必要があります。IClass
TClass
しかし、インターフェイスの名前を変更すると、自動登録が失敗します。タイプ/インターフェース名を一致させる必要がありますか、それとも私のニーズを達成する方法はありますか?
Unity.AutoRegistrationは、タイプ名がインターフェイス名と一致する場合に正常に機能します (たとえば、TClass
and ITClass
. インターフェイス名にプレフィックス「T」を付けないようにしたいのですが、一致IClass
する必要があります。IClass
TClass
しかし、インターフェイスの名前を変更すると、自動登録が失敗します。タイプ/インターフェース名を一致させる必要がありますか、それとも私のニーズを達成する方法はありますか?
著者と相談した後、必要なコードは次のとおりです。
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();
AutoRegistration のコードは長い間変更されていません。codeplexのTecX プロジェクトには、StructureMap の構成のポートとして開始された Unity 用の拡張構成エンジンが含まれています。このエンジンは、登録の規則もサポートしています。
デフォルトの規則の 1 つは、クラスMyService
を interface の実装として登録しますIMyService
。それはそれと同じくらい簡単に見えます:
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);
}
}
カスタムの命名規則が必要な場合は、上記のサンプルを簡単に変更できます。その規則を使用してコンテナーを構成すると、次のようになります。
var builder = new ConfigurationBuilder();
builder.Scan(s =>
{
s.AssembliesFromApplicationBaseDirectory();
s.With(new MyCustomConvention());
});
var container = new UnityContainer();
container.AddExtension(builder);