C# 使用castle windsor在控制台应用程序中使用特定命名空间在程序集中安装服务
我有以下设置:一个C# 使用castle windsor在控制台应用程序中使用特定命名空间在程序集中安装服务,c#,.net,dependency-injection,inversion-of-control,castle-windsor,C#,.net,Dependency Injection,Inversion Of Control,Castle Windsor,我有以下设置:一个控制台应用程序,一个带有一系列服务的服务项目 我试图使用Windsor Castle在应用程序中安装特定的服务,具体取决于它们在应用程序中的名称空间 在我的应用程序中,我可以很好地执行以下操作: Container.Install(Castle.Windsor.Installer.Configuration.FromXmlFile("components.config")); // All services in service DLL var ass
控制台应用程序
,一个带有一系列服务的服务项目
我试图使用Windsor Castle在应用程序中安装特定的服务,具体取决于它们在应用程序中的名称空间
在我的应用程序中,我可以很好地执行以下操作:
Container.Install(Castle.Windsor.Installer.Configuration.FromXmlFile("components.config"));
// All services in service DLL
var assembly = Assembly.LoadFrom(Server.MapPath("~/bin/LetterAmazer.Business.Services.dll"));
;
Container.Register(
Classes.FromAssembly(assembly)
.InNamespace("LetterAmazer.Business.Services.Services")
.WithServiceAllInterfaces());
Container.Register(
Classes.FromAssembly(assembly)
.InNamespace("LetterAmazer.Business.Services.Services.FulfillmentJobs")
.WithServiceAllInterfaces());
Container.Register(
Classes.FromAssembly(assembly)
.InNamespace("LetterAmazer.Business.Services.Services.PaymentMethods.Implementations")
.WithServiceAllInterfaces());
// All factories in service DLL
Container.Register(
Classes.FromAssembly(assembly)
.InNamespace("LetterAmazer.Business.Services.Factory")
.WithServiceAllInterfaces());
Container.Register(Component.For<LetterAmazerEntities>());
但是,我很难让“使用特定名称空间注册所有服务”
在我之前制作的一个web应用程序中,我得到了以下代码。然而,当我在控制台应用程序中使用Container.Register时,我似乎无法稍后解析服务
我以前在web应用程序中使用的代码:
Container.Install(Castle.Windsor.Installer.Configuration.FromXmlFile("components.config"));
// All services in service DLL
var assembly = Assembly.LoadFrom(Server.MapPath("~/bin/LetterAmazer.Business.Services.dll"));
;
Container.Register(
Classes.FromAssembly(assembly)
.InNamespace("LetterAmazer.Business.Services.Services")
.WithServiceAllInterfaces());
Container.Register(
Classes.FromAssembly(assembly)
.InNamespace("LetterAmazer.Business.Services.Services.FulfillmentJobs")
.WithServiceAllInterfaces());
Container.Register(
Classes.FromAssembly(assembly)
.InNamespace("LetterAmazer.Business.Services.Services.PaymentMethods.Implementations")
.WithServiceAllInterfaces());
// All factories in service DLL
Container.Register(
Classes.FromAssembly(assembly)
.InNamespace("LetterAmazer.Business.Services.Factory")
.WithServiceAllInterfaces());
Container.Register(Component.For<LetterAmazerEntities>());
当我得到一个“服务无法解决”
该代码在BackgroundService类中运行,代码如下:
public void Start()
{
logger.Info("Starting Background Service...");
Container.Install(Castle.Windsor.Installer.Configuration.FromXmlFile("components.config"));
ISchedulerFactory scheduleFactory = new StdSchedulerFactory();
scheduler = scheduleFactory.GetScheduler();
scheduler.Start();
ThreadStart threadStart = new System.Threading.ThreadStart(ScheduleJobs);
new Thread(threadStart).Start();
logger.Info("DONE!");
}
总而言之:如何在控制台应用程序的外部DLL中使用特定的命名空间注册所有服务/类
编辑:
ServiceFactory.cs:
public class ServiceFactory
{
private static ServiceFactory instance = new ServiceFactory();
private IWindsorContainer container = new WindsorContainer();
private ServiceFactory()
{
}
/// <summary>
/// Gets the container.
/// </summary>
/// <value>The container.</value>
public static IWindsorContainer Container
{
get { return instance.container; }
}
/// <summary>
/// Gets this instance.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static T Get<T>()
{
return instance.container.Resolve<T>();
}
/// <summary>
/// Gets all this instance.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <returns></returns>
public static IList<T> GetAll<T>()
{
return instance.container.ResolveAll<T>();
}
/// <summary>
/// Gets the specified name.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="name">The name.</param>
/// <returns></returns>
public static T Get<T>(string name)
{
return (T)instance.container.Resolve<T>(name);
}
/// <summary>
/// Gets all the specified name.
/// </summary>
/// <typeparam name="T"></typeparam>
/// <param name="name">The name.</param>
/// <returns></returns>
public static IList<T> GetAll<T>(string name)
{
return instance.container.ResolveAll<T>(name);
}
}
但是,我可以看到在调试中,IOrderService存在于容器中的“所有服务”中
编辑-3
public interface IOrderService
{
Order Create(Order order);
Order Update(Order order);
void UpdateByLetters(IEnumerable<Letter> letters);
List<Order> GetOrderBySpecification(OrderSpecification specification);
Order GetOrderById(int orderId);
Order GetOrderById(Guid orderId);
void Delete(Order order);
List<OrderLine> GetOrderLinesBySpecification(OrderLineSpecification specification);
void ReplenishOrderLines(Order order);
}
我认为在控制台应用程序中也可以做同样的事情。您只需创建程序集实例。考虑到程序集位于同一文件夹中,这应该可以:
Assembly assembly = Assembly.LoadFrom("MyAssembly.dll");
Container.Register(
Classes.FromAssembly(assembly)
.InNamespace("MyNamespace")
.WithServiceAllInterfaces());
执行此操作时,无法解析ScheduleJob类中的服务。servicefactory没有注册这些类,当我执行以下操作时,它不会解析服务。Get()@LarshHoldGaard这意味着至少您正确加载了程序集,否则它将引发异常。你能检查IOrderService实现是否是公共的吗?让我澄清一下。在BackgroundService.cs中,它完美地加载了服务,我可以在ServiceFactory中看到它们。然而,当进入我的ScheduleJob时,它是空的。当我使用安装调用时,我可以在ScheduleJob中调用它们。@LarshHoldGaard何时尝试解决它们?是在注册之前吗?流程是:backgroundservice有一个名为Start()的方法,该方法注册所有类(您可以看到“Start()”方法)。然后,我用deliveryjobs类启动一个新线程,在注册服务之后,您确实需要创建一个SSCCE-()。这样做可能有助于解决您的问题,并使其他人(和我)更容易提供帮助。
Assembly assembly = Assembly.LoadFrom("MyAssembly.dll");
Container.Register(
Classes.FromAssembly(assembly)
.InNamespace("MyNamespace")
.WithServiceAllInterfaces());