Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Getting TinyIoc current container in a Nancy project

I'm building a small Nancy web project.

In a method of one of my classes (not a nancy module), I would like to basically do:

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

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

Naturally, in my above code, I'm getting:

Unable to resolve type: My.Namespace.IMyThing

So, I guess I'm not getting the same container registered in my bootstrapper?

Is there a way to get at it?

EDIT

To flesh out a bit more of what I'm trying to do:

Basically, my url structure looks something like:

/{myType}/{myMethod}

So, the idea being, going to: /customer/ShowAllWithTheNameAlex would load the Customer service, and execute the showAllWithTheNameAlex method

How I do this is:

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

I then have an abstract base class, with a method GetService that returns the service.
It's here that i'm trying to use the TinyIoC.TinyIoCContainer.Current.Resolve();
In this case, it would 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's my implementation of the service.

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

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

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

Finally, I have my Nancy Module, that looks like:

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
    }
}
like image 564
Alex Avatar asked Sep 26 '12 16:09

Alex


1 Answers

@alexjamesbrown - The short answer is, you don't. Nancy was specifically designed so that you did not deal with the container directly. You mention that the class, that you want to take a dependency on IMyThing, is not a NancyModule. Well this is not an issue, as long as one of your modules has a reference to it, then those dependencies can 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 just fine and Greeter will have it's dependency on IGreetingMessageService satisfied at runtime

like image 115
TheCodeJunkie Avatar answered Nov 19 '22 17:11

TheCodeJunkie