We are writing a multi-tenant application.  The application has two
parts: a website and an importer, which loads data from a CSV file
into the database.  The multi-tenancy for the website is driven by a
claim associated with the identity of the logged-in user.  The multi-
tenancy for the importer is driven by the location of the CSV file -
each tenant having a specific location in the filesystem.

In order to support this, we have created an implementation of
ISubDependencyResolver called MultiTenancySubDependencyResolver.  It
depends on a IUserContextProvider to provide the name of the current
tenant. There is one implementation of IUserContextProvider for the
website and one for the importer.

Our initial approach was to have the MultiTenancySubDependencyResolver
ask the container to resolve IUserContextProvider every time its
CanResolve method was called:

public bool CanResolve(CreationContext context, ISubDependencyResolver
contextHandlerResolver, ComponentModel model, DependencyModel
dependency) {
    var userContext =
_kernel.Resolve<IUserContextProvider>().GetCurrentTenant;

    if(userContext.IsAnonymous) {
        return false;
    }

    return true;
}

That worked fine for the website.  However, the implementation of
IUserContextProvider used by the importer has dependencies that need
to be satisfied from the container.  This led to a cyclic dependency
because when GetCurrent was called the
MultiTenancySubDependencyResolver was immediately asked if it
CanResolve the first dependency, causing another request to the
container to resolve IUserContextProvider, ad infinitum.

Is there any way we can prevent the MultiTenancySubDependencyResolver
from trying to resolve its own dependencies?  I tried adding guard
clauses to check if the type we were being asked to resolve was
IUserContextProvider and, if so, return false.  That worked fine for
the website but because the importer user-context provider has further
dependencies we would have had to add guard clauses for them too.
That would have led to a circular assembly reference (and was starting
to smell anyway).

Experience tells me when you are having to fight this hard with a
library then you are doing something wrong.  Thus, I am reaching out
to the community to show me the error of my ways!  Is there something
fundamentally wrong with my design?

Finally, I should point out that the lifestyle of the websites
IUserContextProvider is PerWebRequest and the lifestyle of the
importers is PerThread.

Thanks in advance.


-- 
You received this message because you are subscribed to the Google Groups 
"Castle Project Users" group.
To post to this group, send email to [email protected].
To unsubscribe from this group, send email to 
[email protected].
For more options, visit this group at 
http://groups.google.com/group/castle-project-users?hl=en.

Reply via email to