8

我正在构建一个小型 Nancy Web 项目。

在我的一个类(不是 nancy 模块)的方法中,我想基本上做:

var myThing = TinyIoC.TinyIoCContainer.Current.Resolve<IMyThing>();

.Current但是, (非公共成员,_RegisteredTypes)中只有一个注册, 即:
TinyIoC.TinyIoCContainer.TypeRegistration

自然,在我上面的代码中,我得到:

无法解析类型:My.Namespace.IMyThing

所以,我想我没有在我的引导程序中注册相同的容器?

有没有办法解决它?

编辑

为了充实我正在尝试做的事情:

基本上,我的 url 结构看起来像:

/{myType}/{myMethod}

因此,想法是:/customer/ShowAllWithTheNameAlex 将加载Customer服务,并执行该showAllWithTheNameAlex方法

我的做法是:

public interface IService
{
    void DoSomething();
    IEnumerable<string> GetSomeThings();
}

然后我有一个抽象基类,带有一个返回服务的方法 GetService。
我在这里尝试使用 TinyIoC.TinyIoCContainer.Current.Resolve();
在这种情况下,它将是 TinyIoC.TinyIoCContainer.Current.Resolve("typeName");

public abstract class Service : IService
{
    abstract void DoSomething();
    abstract IEnumerable<string> GetSomeThings();

    public static IService GetService(string type)
    {
        //currently, i'm doing this with reflection....
    }
}

这是我的服务实现。

public class CustomerService : Service
{
    public void DoSomething()
    {
        //do stuff
    }

    public IEnumerable<string> GetSomeThings()
    {
        //return stuff
    }

    public IEnumerable<Customer> ShowAllWithTheNameAlex()
    {
        //return
    }
}

最后,我有我的 Nancy 模块,它看起来像:

public class MyModule : NancyModule
{
    public MyModule()
    {
        Get["/{typeName}/{methodName}"] = p => ExecuteMethod(p.typeName, p.methodName);
    }

    private dynamic ExecuteMethod(string typeName, string methodName)
    {
        var service = Service.GetService(typeName);

        var result = service.GetType().GetMethod(methodName).Invoke(service, null);

        //do stuff

        return result; //or whatever
    }
}
4

3 回答 3

4

@alexjamesbrown - 简短的回答是,你没有。Nancy 是专门设计的,因此您无需直接处理容器。您提到要依赖的类IMyThing不是 NancyModule。好吧,这不是问题,只要您的模块之一具有对它的引用,那么这些依赖项也可以具有它们自己的依赖项,这些依赖项将在运行时得到满足。

public interface IGreetingMessageService
{
   string GetMessage();
}

public class GreetingMessageService: IGreetingMessageService
{
   public string GetMessage()
   {
      return "Hi!";
   }
}

public interface IGreeter
{
   string Greet();
}

public class Greeter
{
   private readonly IGreetingMessageService service;

   public Greeter(IGreetingMessageService service)
   {
      this.service = service;
   }

   public string Greet()
   {
      return this.service.GetMessage();
   }
}

public class GreetingsModule : NancyModule
{
   public GreetingModule(IGreeter greeter)
   {
      Get["/"] = x => greeter.Greet();
   }
}

以上将正常工作,并且Greeter将依赖IGreetingMessageService于运行时满足

于 2012-09-26T18:11:43.317 回答
0

我有一个非常相似的问题,需要“共享”容器。这是一个问题的原因是我的程序使用 Nancy 自托管作为服务运行以提供 REST API。我的模块具有由 Nancy 本身注入的依赖项,但未从模块引用的应用程序的其他部分也需要注入依赖项。多个容器在这里(或任何地方)不是一个明智的选择,我需要在 Nancy 和应用程序的其余部分之间共享容器。

我只是做了以下事情(我正在使用 Autofac,但我怀疑 TinyIoC 类似)

public class Bootstrapper : AutofacNancyBootstrapper
{
    private static readonly Lazy<ILifetimeScope> container = new Lazy<ILifetimeScope>(RegisterTypes);
    public static ILifetimeScope Container => container.Value;

    protected override ILifetimeScope GetApplicationContainer()
    {
        return container.Value;
    }

    // Create container and register my types
    private static ILifetimeScope RegisterTypes()
    {
        var builder = new ContainerBuilder();

        // Register all my own types.....

        return builder.Build();
    }
}

然后,在我的主代码中,我可以自己使用容器

public class Program
{
    public static void Main(string[] args)
    {
        // Resolve main service with all its dependencies
        var service = Bootstrapper.Container.Resolve<Service>();
        service.Run();
    }
}

由于我的 NancyHost 在服务中,因此容器在第一次使用时被构造(一次),main然后在 Nancy 开始创建Bootstrapper自身时使用此静态。

在一个理想的世界里,我真的不想要一个全局可访问的容器,通常它是main函数的本地容器。

于 2017-06-28T15:22:05.973 回答
-1

在这种特殊情况下,“不直接处理容器”是很成问题的:

公共接口 IFoo {}

公共类 Foo : IFoo { public Foo(string bar) {} }

假设 IFoo 已经Nancy 模块的构造函数依赖项。

注意 Foo 构造函数的字符串依赖。当遇到作为 Nancy 模块依赖项时,我需要与容器通信以将该构造函数用于 IFoo 单例。我需要在 NancyFx 使用的 TinyIoC 实例上注册它,并传入 bar 的实际值。

于 2016-08-31T04:33:29.323 回答