Sign Up

Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.

Have an account? Sign In

Have an account? Sign In Now

Sign In

Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.

Sign Up Here

Forgot Password?

Don't have account, Sign Up Here

Forgot Password

Lost your password? Please enter your email address. You will receive a link and will create a new password via email.

Have an account? Sign In Now

You must login to ask a question.

Forgot Password?

Need An Account, Sign Up Here

Please briefly explain why you feel this question should be reported.

Please briefly explain why you feel this answer should be reported.

Please briefly explain why you feel this user should be reported.

Sign InSign Up

The Archive Base

The Archive Base Logo The Archive Base Logo

The Archive Base Navigation

  • SEARCH
  • Home
  • About Us
  • Blog
  • Contact Us
Search
Ask A Question

Mobile menu

Close
Ask a Question
  • Home
  • Add group
  • Groups page
  • Feed
  • User Profile
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Buy Points
  • Users
  • Help
  • Buy Theme
  • SEARCH
Home/ Questions/Q 7444949
In Process

The Archive Base Latest Questions

Editorial Team
  • 0
Editorial Team
Asked: May 29, 20262026-05-29T11:42:00+00:00 2026-05-29T11:42:00+00:00

I am currently using TopShelf with Ninject to create a Windows Service. I have

  • 0

I am currently using TopShelf with Ninject to create a Windows Service. I have the following code to setup the Windows Service using TopShelf:

static void Main(string[] args)
{
    using (IKernel kernel = new StandardKernel(new NinjectDependencyResolver()))
    {
        Settings settings = kernel.Get<Settings>();

        var host = HostFactory.New(x =>
        {
            x.Service<BotService>(s =>
            {
                s.ConstructUsing(name => new BotService(settings.Service.TimeInterval));
                s.WhenStarted(ms => ms.Start());
                s.WhenStopped(ms => ms.Stop());
            });

            x.RunAsNetworkService();

            x.SetServiceName(settings.Service.ServiceName);
            x.SetDisplayName(settings.Service.DisplayName);
            x.SetDescription(settings.Service.Description);
        });

        host.Run();
    }
}

This is the object behind the Windows Service doing all the work:

public class BotService
{
    private readonly Timer timer;

    public BotService(double interval)
    {
        this.timer = new Timer(interval) { AutoReset = true };
        this.timer.Elapsed += (sender, eventArgs) => Run();
    }

    public void Start()
    {
        this.timer.Start();
    }

    public void Stop()
    {
        this.timer.Stop();
    }

    private void Run()
    {
        IKernel kernel = new StandardKernel(new NinjectDependencyResolver());

        Settings settings = kernel.Get<Settings>();

        if (settings.Service.ServiceType == 1)
        {
            // The interface implementation has constructor injection of IUnitOfWork and IMyRepository
            kernel.GetAll<IExternalReportService>().Each(x => x.Update());
        }

        if (settings.Service.ServiceType == 2)
        {
            // The interface implementation has constructor injection of IUnitOfWork and IMyRepository
            kernel.GetAll<IExternalDataService>().Each(x => x.GetData());
        }

        kernel.Get<IUnitOfWork>().Dispose();
        kernel.Dispose();
    }
}

These are the Ninject bindings:

public class NinjectDependencyResolver : NinjectModule
{
    public override void Load()
    {
        Settings settings = CreateSettings();
        ConnectionStringSettings connectionStringSettings = ConfigurationManager.ConnectionStrings["DB"];

        Bind<IDatabaseFactory>().To<DatabaseFactory>()
                                .InThreadScope()
                                .WithConstructorArgument("connectionString", connectionStringSettings.Name);

        Bind<IUnitOfWork>().To<UnitOfWork>();
        Bind<IMyRepository>().To<MyRepository>();
        Bind<IExternalReportService>().To<ReportService1>();
        Bind<IExternalReportService>().To<ReportService2>();
        Bind<IExternalDataService>().To<DataService1>();
        Bind<IExternalDataService>().To<DataService2>();

        Bind<Settings>().ToConstant(settings);
    }

    private Settings CreateSettings()
    {
        // Reads values from app.config and returns object with settings
    }
}

First off let me say that I am not happy with this code. When the application starts an instance of the kernel is created, the values from settings are fetched and I use TopShelf to create a Windows Service using the BotService object.

Everytime the timer event fires the Run() method is executed. Here another instance of the kernel is created, again it reads the settings and depending on the value the kernel fetches all implementations of the interface and executes the corresponding method. Each of these implementations has a constructor where IUnitOfWork and IMyRepository are injected for data access.

When the methods are finished I dispose of the context and dispose of the kernel.

Why did I set it up like this? Originally I only created one kernel in the Main and used a constructor in the BotService to inject the implementations as opposed to creating another instance of the kernel. The problem was that the DatabaseFactory needed a InSingletonScope or InThreadScope to work.

If I used InSingeltonScope the context would become stale and eventually issues would start to creep up where the context is invalid. If I used InThreadScope I run into the same issue because it doesn’t dispose the objects once the thread is done. Eventually Run() used a previously used thread and an exception occurrs since I already disposed of the Context. If I removed the line of code where I dispose of the context well then we run into the same issue as InSingletonScope where we end up with a stale context when the thread is re-used.

This lead to the current code where I am guaranteed that each Time Run() is executed the context is around until it is done where it is disposed and since the kernel is disposed as well I ensure that next time the same thread is used we get a new context since the kernel is re-created (at least I think this is what’s happening).

My Ninject skills are not that advanced and there is very limited information out there on how to approach this problem. I think the right approach would be to create one kernel in the Main only and then be able to inject what I need into the BotService object via a constructor. But at the same time the Context needs to be created for each Run() in order to avoid a stale context which would happen if I used one of the scopes mentioned above with this approach.

How can I modify the example above so it would be correct? I am currently using Ninject 2.2.1.4.

  • 1 1 Answer
  • 0 Views
  • 0 Followers
  • 0
Share
  • Facebook
  • Report

Leave an answer
Cancel reply

You must login to add an answer.

Forgot Password?

Need An Account, Sign Up Here

1 Answer

  • Voted
  • Oldest
  • Recent
  • Random
  1. Editorial Team
    Editorial Team
    2026-05-29T11:42:04+00:00Added an answer on May 29, 2026 at 11:42 am

    First, let me try and distill your problem down a bit. It sounds to me like you have a dependency (DatabaseFactory) that needs a custom scope (or life-time as others may refer to them as). It sounds to me like you want the same instance of DatabaseFactory returned for the duration of a single execution of Run.

    If this is correct, I think you should be able to accomplish this in one of two ways:

    1. If you don’t mind all instances being refreshed for each execution of Run:

      private StandardKernel _kernel /* passed into constructor */;
      
      public void Run()
      {
          using (var block = _kernel.BeginBlock())
          {
              var settings = block.Get<Settings>();
              if (settings.Service.ServiceType == 1)
              {
                  // The interface implementation has constructor injection of IUnitOfWork and IMyRepository
                  block.GetAll<IExternalReportService>().Each(x => x.Update());
              }
      
              if (settings.Service.ServiceType == 2)
              {
                  // The interface implementation has constructor injection of IUnitOfWork and IMyRepository
                  block.GetAll<IExternalDataService>().Each(x => x.GetData());
              }
          }
      }
      
    2. If you only want the specific instances to be refreshed for each execution, you should be able to accomplish this using a custom scope object (have a look at InScope() method and this post from Nate). Unfortunately, you would probably run into a host of multi-threading issues since Timer may call Run before another thread has finished running.
    • 0
    • Reply
    • Share
      Share
      • Share on Facebook
      • Share on Twitter
      • Share on LinkedIn
      • Share on WhatsApp
      • Report

Sidebar

Related Questions

I am currently using TopShelf with a Console Application to create a Windows Service.
I am currently using Windows Server 2008 Standard and have several Hyper V machines.
I am currently using matplotlib.pyplot to create graphs and would like to have the
Im currently using a method that looks like the following code to add script
Currently using System.Web.UI.WebControls.FileUpload wrapped in our own control. We have licenses for Telerik. I
I am currently using the following command to upload my site content: scp -r
Our team is currently using some ported code from an old architecture to a
im currently using the SDL-devel-1.2.13-mingw32 library in code blocks 8.02. with the mingw 5.1.6
Currently using wxHTML to display a remote web page in a C++ Windows wxWidgets
Currently using cocos2d. I have a plist data name myplist.plist. Inside the plist are

Explore

  • Home
  • Add group
  • Groups page
  • Communities
  • Questions
    • New Questions
    • Trending Questions
    • Must read Questions
    • Hot Questions
  • Polls
  • Tags
  • Badges
  • Users
  • Help
  • SEARCH

Footer

© 2021 The Archive Base. All Rights Reserved
With Love by The Archive Base

Insert/edit link

Enter the destination URL

Or link to existing content

    No search term specified. Showing recent items. Search or use up and down arrow keys to select an item.