You'd better create manually UnityContainer and inject it into your service locator:
public class ServiceLocator
{
public static void SetServiceLocatorProvider(IServiceLocator serviceLocator)
{
Instance = serviceLocator;
}
public static void SetServiceLocatorProvider(Func<IServiceLocator> serviceLocator)
{
Instance = serviceLocator();
}
public static IServiceLocator Instance { get; private set; }
}
public class ServiceLocatorContainer : IServiceLocator
{
private readonly IUnityContainer _unityContainer;
public ServiceLocatorContainer(IUnityContainer unityContainer)
{
_unityContainer = unityContainer;
}
//skipped for simplicity sake
}
public abstract class ApplicationControllerBase
{
/// <summary>
/// Создать экземпляр Unity контейнера
/// </summary>
private IUnityContainer CreateContainer()
{
return new UnityContainer();
}
protected virtual void ConfigureContainer()
{
RegisterTypeIfMissing(typeof(IServiceLocator), typeof(ServiceLocatorContainer), true);
RegisterTypeIfMissing(typeof(ISharedAssemblyInitializer), typeof(SharedAssemblyInitializer), true);
ServiceLocator.SetServiceLocatorProvider(() => this.Container.Resolve<IServiceLocator>());
}
protected void RegisterTypeIfMissing(Type fromType, Type toType, bool registerAsSingleton)
{
if (Container.IsTypeRegistered(fromType))
{
}
else
{
if (registerAsSingleton)
{
Container.RegisterType(fromType, toType, new ContainerControlledLifetimeManager());
}
else
{
Container.RegisterType(fromType, toType);
}
}
}
public virtual void Run()
{
this.Container = CreateContainer();
this.ConfigureContainer();
}
public IUnityContainer Container { get; private set; }
}
this is a simplified version of prism extension to unity. see more detailed sources of modulesmanager class in prism.
app starts with Run method. You create container and register your servicelocator in it. Wile registering, UnityContainer creates instance of it and pass itself into ctor:
public ServiceLocatorContainer(IUnityContainer unityContainer)
{
_unityContainer = unityContainer;
}
then, using SetServiceLocatorProvider method you assign to Instance property instance of servicelocator class, that has reference to unity container within. Such solution also gives abstraction of concrete DI container. And you can reference to your service locator from anywhere in your code.
1) Injectiong into constructor
public class RLoginABS
{
IServiceLocator serviceLocator;
public RLoginABS(IServiceLocator serviceLocator)
{
this.serviceLocator = serviceLocator;
}
public void Login(string user, string password)
{
REnvironmentRWS environment = REnvironmentRWS.Current;
serviceLocator.RegisterInstance<IEnvironmentRWS>(environment as IEnvironmentRWS);
}
}
or using static class:
shellViewModel = ServiceLocator.Instance.Resolve<IShellViewModel>();
ps: IServiceLocator interface, which is an abstraction of concrete implementation of DI container:
public interface IServiceLocator
{
void Register<TInterface, TImplementor>() where TImplementor : TInterface;
void Register(Type TInterface, Type TImplementor);
void RegisterAsSingleton<TInterface, TImplementor>() where TImplementor : TInterface;
T Resolve<T>();
}
its methods wraps concrete container's methods, for example:
public void Register(Type TInterface, Type TImplementor)
{
_unityContainer.RegisterType(TInterface, TImplementor);
}
Hope - it helps!