実際には、上書きするためにXMLファイルを結合し、デフォルトの流暢な登録を使用する素晴らしいソリューションが見つかりました。
fluent-APIは、implのフルネームをデフォルトキーとして使用します。オンザフライでは、Fluent-APIのキーコンベンションを模倣するために、xml-configのIDを上書きします。
次に、Kernel.ComponentRegistered
を聞きながらxml-configを登録します。
その後、xmlがまだサービスを定義していないサービスをcode-configから追加します。
(それはしばらく前だと、私はただのコードをコピー&ペースト。うまくいけば、あなたはそれが動作します。あなたが何か問題を見つけた場合、私は編集をやる)私は、サービスを登録する前に、その後
IList<Type> unnamedServices = new List<Type>();
IDictionary<string, Type> namedServices = new Dictionary<string, Type>();
ComponentDataDelegate registered = captureRegistrations(unnamedServices, namedServices);
container.Kernel.ComponentRegistered += registered;
// The method that captures the services
private static ComponentDataDelegate captureRegistrations(
IList<Type> unnamedServices, IDictionary<string, Type> namedServices)
{
return (key, handler) =>
{
if (handler.ComponentModel.Name == handler.ComponentModel.Implementation.FullName)
{
unnamedServices.Add(handler.Service);
}
else
{
namedServices.Add(key, handler.Service);
}
};
}
をコードでは、すでに登録されているかどうかを確認します。これをより簡単にする基本クラスも作成しました。このアプリケーションの設定です:あなたは非常に単純に上書きする必要がある場所でこれを行うことができます (ロギングCommons.Loggingからである)
public class WindsorConfigurationSkeleton
{
private static readonly ILog _log = LogManager.GetLogger(
typeof(WindsorConfigurationSkeleton));
internal static IWindsorContainer createWith(
IRegistration[] customs, string configFile, params Func<IEnumerable<IRegistration>>[] methods)
{
IWindsorContainer container = new WindsorContainer();
BugFix.Kernel = container.Kernel;
container.AddFacility("factory.support", new FactorySupportFacility());
IList<Type> unnamedServices = new List<Type>();
IDictionary<string, Type> namedServices = new Dictionary<string, Type>();
ComponentDataDelegate registered = captureRegistrations(unnamedServices, namedServices);
container.Kernel.ComponentRegistered += registered;
if (customs != null)
{
container.Register(customs);
}
if (configFile != null)
{
tryAddXmlConfig(container, configFile);
}
container.Kernel.ComponentRegistered -= registered;
if (methods != null && methods.Length > 0)
{
container.Register(union(unnamedServices, namedServices, methods));
}
return container;
}
private static ComponentDataDelegate captureRegistrations(
IList<Type> unnamedServices, IDictionary<string, Type> namedServices)
{
return (key, handler) =>
{
if (handler.ComponentModel.Name == handler.ComponentModel.Implementation.FullName)
{
var text = unnamedServices.Contains(handler.Service) ? "another" : "default";
_log.Info(
m => m(
"Registered {2} service for {0} with {1}.",
handler.Service.GetDisplayName(),
handler.ComponentModel.Implementation.GetDisplayName(),
text
));
unnamedServices.Add(handler.Service);
}
else
{
var text = namedServices.ContainsKey(key) ? "another" : "default";
_log.Info(
m => m(
"Registered {3} service {0} with name '{1}' and {2}.",
handler.ComponentModel.Service,
handler.ComponentModel.Name,
handler.ComponentModel.Implementation.GetDisplayName(),
text
));
namedServices.Add(key, handler.Service);
}
};
}
protected static void tryAddXmlConfig(IWindsorContainer container, string filename)
{
var fi = Resources.GetFileFromResourceHierarchy(typeof(ApplicationContext).Namespace, filename);
if (fi == null) {
return;
}
var configFile = fi.FullName;
var xd = immitateFluentApiDefaultIdBehaviour(configFile);
container.Install(Configuration.FromXml(new StaticContentResource(xd.OuterXml)));
}
private static XmlDocument immitateFluentApiDefaultIdBehaviour(string configFile)
{
var xd = new XmlDocument();
xd.Load(configFile);
foreach (
XmlElement component in
xd.SelectNodes("/configuration/components/component[@type and (not(@id) or @id = '')]"))
{
var type = Type.GetType(component.GetAttribute("type"), true);
component.SetAttribute("id", type.FullName);
}
return xd;
}
private static IRegistration[] union(
IList<Type> unnamed, IDictionary<string, Type> named, params Func<IEnumerable<IRegistration>>[] methods)
{
var all = new List<IRegistration>();
foreach (var method in methods)
{
foreach (var registration in method())
{
var registrationType = registration.GetType();
if (registrationType.IsGenericTypeOf(typeof(ComponentRegistration<>)))
{
var componentType = registrationType.GetGenericArgumentsFor(typeof(ComponentRegistration<>))[0];
var name = (string)registrationType.GetProperty("Name").GetValue(registration, null);
if (name != null)
{
if (named.ContainsKey(name))
{
_log.Debug(
m => m("Skipped registering default named component {0}.", name));
continue;
}
}
else if (unnamed.Contains(componentType))
{
_log.Debug(
m => m("Skipped registering default component for type {0}.", componentType));
continue;
}
all.Add(registration);
}
else
{
all.Add(registration);
}
}
}
return all.ToArray();
}
}
私は流暢な配線をオーバーライドするxmlファイルを持っています。しかし、私はxmlファイルを最初に読み込み、xmlファイルがそれらを再定義するときにコードから設定を追加しないことで、今解決しました。 –
これはもっと良いアプローチです –
@ラス:もっと具体的にすることができますか?私はここでも同じ問題があります。私はコア配線を持っており、コア配線を変更することなく別の実装に切り替える必要があります。 – Marcus