I've been tasked with establishing code patterns to use for new applications that we'll be building. An early decision was made to build our applications and libraries using Prism & MEF with the intent of simplifying testing & reuse of functionality across applications.
As our code base has grown I've run into a problem. Suppose we have some base library that needs access to some system - let's say a user management system:
public interface IUserManagementSystem
{
IUser AuthenticateUser(string username, string password);
}
// ...
public class SomeClass
{
[ImportingConstructor]
public SomeClass(IUserManagementSystem userSystem){ }
}
We can now create an object of type SomeClass using the ServiceLocator, but ONLY if an implementation of IUserManagementSystem has been registered. There is no way to know (at compile-time) whether creation will succeed or fail, what implementations are needed or other critical information.
This problem becomes even more complicated if we use the ServiceLocator in the library.
Finding the now-hidden dependencies has become a bigger problem than hard-coded dependencies were in legacy applications. The IoC and Dependency Injection patterns aren't new, how are we supposed to manage dependencies once we take that job away from the compiler? Should we avoid using ServiceLocator (or other IoC containers) in library code entirely?
EDIT: I'm specifically wondering how to handle cross-cutting concerns (such as logging, communication and configuration). I've seen some recommendations for building a CCC project (presumably making heavy use of singletons). In other cases (Is the dependency injection a cross-cutting concern?) the recommendation is to use the DI framework throughout the library leading back to the original problem of tracking dependencies.
Dependency Inject (DI) "friendly" library is somewhat relevant in that it explains how to structure code in a manner that can be used with or without a DI framework, but it doesn't address whether or not it makes sense to use DI within a library or how to determine the dependencies a given library requires. The marked answers there provide solid architectural advice about interacting with a DI framework but it doesn't address my question.