Getting TinyIoc of the current container in a Nancy project

I am building a small Nancy web project.

In the method of one of my classes (and not in the nancy module) I would like to basically execute:

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

However, .Current is only one registration in .Current (not public members, _RegisteredTypes), which:
TinyIoC.TinyIoCContainer.TypeRegistration

Naturally, in my code above, I get:

Unable to resolve type: My.Namespace.IMyThing

So, I suppose that I am not getting the same container registered in my boot file?

Is there any way to get to it?

EDIT

Extract a bit more of what I'm trying to do:

Basically, my url structure looks something like this:

/ {MyType} / {MyMethod}

So the idea is that: / customer / ShowAllWithTheNameAlex will load the Customer service and execute the showAllWithTheNameAlex method

How do i do this:

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

Then I have an abstract base class with a GetService method that returns a service.
It is here that I am trying to use TinyIoC.TinyIoCContainer.Current.Resolve (); In this case, it will be 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.... } } 

Here is my service implementation.

 public class CustomerService : Service { public void DoSomething() { //do stuff } public IEnumerable<string> GetSomeThings() { //return stuff } public IEnumerable<Customer> ShowAllWithTheNameAlex() { //return } } 

Finally, I have a Nancy module that looks like this:

 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 } } 
+8
inversion-of-control tinyioc nancy
source share
3 answers

@alexjamesbrown - Short answer: no. Nancy has been specially designed so that you do not touch the container directly. You note that the class you want to set the dependency on IMyThing is not NancyModule. Well, this is not a problem if one of your modules has a link to it, then these dependencies may also have their own dependencies that will be satisfied at runtime.

 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(); } } 

The above will work fine, and Greeter will have an IGreetingMessageService dependency satisfied at runtime

+4
source share

I had a very similar problem requiring a β€œshared” container. The reason for this is because my program works as a service, using Nancy's own hosting to provide the REST API. My modules have dependencies that are introduced by Nancy himself, but for other parts of the application that are not referenced by the modules, nested dependencies are also required. Multiple containers here are not a reasonable option (or anywhere really), I need to split the container between Nancy and the rest of the application.

I just did the following (I use Autofac, but I suspect TinyIoC is similar)

 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(); } } 

Then in my main code I can use the container myself

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

Since my NancyHost is in the Service, the container is created (once) the first time it is used in main , this static one is then used when Nancy walks around Bootstrapper itself.

In an ideal world, I would not want a globally accessible container, usually it would be local to the main function.

0
source share

In this particular case, "not dealing directly with the container" is very problematic:

open IFoo interface {}

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

Suppose IFoo already has a constructor dependency on a Nancy module.

Note the dependency of the Foo constructor line. I need to contact the container to use this constructor for the singleton IFoo when it appears as a dependency on the Nancy module. I need to register this with the TinyIoC example used by NancyFx and pass the actual value of bar.

-one
source share

All Articles