故事就是这样:
我有单例类(a.k.a ServiceLocator),您可以使用“CreateInstance()”方法获取实例。同时,我们将Unity添加到我们的应用程序中,并使用标准配置文件对其进行配置。
当我尝试映射接口IServiceLocator
以获取ServiceLocator
的实例并将其注册到unity配置文件中时,问题就开始了。正如您可能猜到的那样,ServiceLocator没有公共构造函数(即singleton),因此,当我执行unity.resolve<IServiceLocator>()
时,unity不能创建它....
我的问题:有没有办法告诉Unity(通过配置文件)使用CreateInstance()
而不是尝试执行默认构造函数?如果没有,如果您还有其他想法可以做什么,我将不胜感激。
请不要建议我将构造函数更改为public,假设我暂时不能这样做。
答案 0 :(得分:0)
您最好手动创建UnityContainer并将其注入服务定位器:
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; }
}
这是棱镜扩展到统一的简化版本。在棱镜中查看modulesmanager类的更详细的来源。 应用程序以Run方法启动。您创建容器并在其中注册您的servicelocator。 Wile注册,UnityContainer创建它的实例并将自己传递给ctor:
public ServiceLocatorContainer(IUnityContainer unityContainer)
{
_unityContainer = unityContainer;
}
然后,使用SetServiceLocatorProvider方法分配给servicelocator类的Instance属性实例,该实例引用了unity容器。这种解决方案还提供了具体DI容器的抽象。您可以从代码中的任何位置引用您的服务定位器。 1)注入构造函数
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);
}
}
或使用静态类:
shellViewModel = ServiceLocator.Instance.Resolve<IShellViewModel>();
ps:IServiceLocator接口,它是DI容器的具体实现的抽象:
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>();
}
它的方法包装了具体容器的方法,例如:
public void Register(Type TInterface, Type TImplementor)
{
_unityContainer.RegisterType(TInterface, TImplementor);
}
希望 - 它有所帮助!