0

After introducing messaging in my application it seems I've found a bit of a smell.

In my multi tenant application, the file system is abstracted and scoped for each tenant. So if a service needs to create files, then we inject an instance of IFileSystem which will be scoped to the tenants directory/container.

This is achieved by configuring structuremap to construct the IFileSystem implementation by getting of a contextual object that has the current users site.

Now we need to use the filesystem when there is no context and no current user (on a background thread). Here's a simple example:

    public class SiteContext
    {
        public string SiteId { get { return "Site123"; } }
    }

    public class FileSystemSettings
    {
        public string BaseDirectory { get; set; }
    }

    public interface IFileSystem { }

    public class DefaultFileSystem : IFileSystem
    {
        public DefaultFileSystem(FileSystemSettings settings)
        {

        }
    }

    public interface ISomeService { }

    public class SomeService : ISomeService
    {
        public SomeService(IFileSystem fileSystem)
        {

        }
    }

    public class TestMessageHandler : IMessageHandler<TestMessage>
    {
        public TestMessageHandler(ISomeService someService)
        {
            // oO we don't have access to site context here :(
        }
    }

I suppose I could change my FileSystem implementation to expose the FileSystemSettings as a property so it can be set afterwards.

However, even doing this would still require me to construct my ISomeService object manually, which is a pain as some of my services have a number of dependencies = lots of calls to ObjectFactory.GetInstance...

Ideas?

rcaval
  • 762
  • 5
  • 12
Ben Foster
  • 34,340
  • 40
  • 176
  • 285
  • http://stackoverflow.com/questions/1943576/is-there-a-pattern-for-initializing-objects-created-via-a-di-container/1945023#1945023 – Mark Seemann Jul 17 '11 at 21:40
  • Can you clarify the question? How do you intend to use SiteContext? Show code that is working, and point out the code that isn't. – Joshua Flanagan Jul 18 '11 at 00:09

1 Answers1

1

You could use nested containers and configure the nested container to have a dummy implementation of your context.

The code would approximately be:

using (var container = ObjectFactory.Container.GetNestedContainer())
{
    container.Configure(config => {
        config.For<ISiteContext>().Use<DummyContext>();
    });

    return container.GetInstance<TestMessageHandler>();
}

This should set a custom (dummy) implementation of ISiteContext without overwriting the global container (ObjectFactory.Container). Of course, I can't give you an appropriate implementation of DummyContext without more information. But this should get you started.

kelloti
  • 8,705
  • 5
  • 46
  • 82