8

私は小さなナンシーのウェブプロジェクトを構築しています。

私のクラスの1つ(ナンシーモジュールではない)のメソッドで、基本的に次のことを行います。

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

.Currentただし、 (非公開メンバー、_RegisteredTypes)には、TinyIoC.TinyIoCContainer.TypeRegistrationの
1つの登録しかありませ ん。

当然、上記のコードでは、次のようになります。

タイプを解決できません: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
    }
}

最後に、次のようなナンシーモジュールがあります。

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-簡単な答えは、あなたはそうしないということです。ナンシーは、コンテナを直接扱わないように特別に設計されました。依存関係を取りたいクラスIMyThingはNancyModuleではないとおっしゃいました。モジュールの1つに参照がある限り、これは問題ではありません。これらの依存関係には、実行時に満たされる独自の依存関係もあります。

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セルフホスティングを使用してRESTAPIを提供するサービスとして実行されるためです。私のモジュールにはナンシー自体によって注入される依存関係がありますが、モジュールから参照されていないアプリの他の部分にも依存関係を注入する必要があります。ここ(または実際にはどこでも)では、複数のコンテナーは賢明なオプションではありません。ナンシーとアプリの他の部分の間でコンテナーを共有する必要があります。

私は単に次のことをしました(私は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はサービス内にあるので、コンテナはでの最初の使用時に(1回)構築mainされ、ナンシーがそれ自体の作成に取り掛かるときにこの静的なものが使用されBootstrapperます。

理想的な世界では、グローバルにアクセス可能なコンテナは必要ありません。通常は、main関数に対してローカルです。

于 2017-06-28T15:22:05.973 に答える
-1

この特定のケースでは、「コンテナを直接処理しない」ことは非常に問題があります。

パブリックインターフェイスIFoo{}

public class Foo:IFoo {public Foo(string bar){}}

IFooすでにNancyモジュールのコンストラクター依存関係であると想定します。

Fooコンストラクターの文字列の依存関係に注意してください。Nancyモジュールの依存関係として検出された場合、IFooシングルトンにそのコンストラクターを使用するためにコンテナーと通信する必要があります。NancyFxが使用するTinyIoCインスタンスにそれを登録し、barの実際の値を渡す必要があります。

于 2016-08-31T04:33:29.323 に答える