我正在使用Provider pattern和Unity。
这是典型的提供程序实现。我有SomeProvider
作为抽象基础提供程序,包含抽象方法以及实例化defaultProvider
的逻辑。
public abstract class SomeProvider : ProviderBase
{
#region provider boilerplate
private const string PROVIDER_NAME = "someProvider";
private static volatile SomeProvider defaultProvider = null;
public static SomeProvider Provider
{
get { return defaultProvider; }
}
private static object providerLockObject = new object();
static SomeProvider()
{
LoadProvider();
}
private static void LoadProvider()
{
if (defaultProvider == null)
{
lock (providerLockObject)
{
if (defaultProvider == null)
{
// exception handling omitted for brevity
var section = ConfigurationManager.GetSection(PROVIDER_NAME)
as BaseProviderConfigurationSection;
defaultProvider = ProvidersHelper.InstantiateProvider(
section.Providers[section.DefaultProvider], typeof(SomeProvider)) as SomeProvider;
}
}
}
}
protected SomeProvider() { }
#endregion
#region abstract methods
public abstract bool DoSomething();
#endregion
}
以下是实施ASomeProvider
的{{1}}。请注意,SomeProvider
具有依赖性ASomeProvider
,但ADependency
没有。
SomeProvider
我在业务层中使用public class ASomeProvider : SomeProvider
{
#region provider boilerplate
private string name;
public override string Name
{
get { return name; }
}
public override void Initialize(string name, NameValueCollection config)
{
this.name = name;
base.Initialize(name, config);
}
#endregion
// Provider pattern needs parameterless ctor and calls this
public ASomeProvider() { }
// constructor injection
public ASomeProvider(ADependency aDependency)
{
this.ADependency = aDependency;
}
[Dependency]
public SomeDependency ADependency { get; set; }
#region methods
public override void DoSomething()
{
// do something
}
#endregion
}
class SomeDependency {}
,如下所示:
ASomeProvider
我有public class SomeBusinessLayer
{
public SomeProvider someProvider;
public SomeBusinessLayer(SomeProvider someProvider)
{
this.someProvider = someProvider;
}
#region methods
public bool DoSomethingWrapper()
{
return someProvider.DoSomething();
}
#endregion
}
工厂,用于使用Unity连接对象并返回对象,如下所示:
BusinessLayerFactory
我遇到的问题是,当我决定获取public static class BusinessLayerFactory
{
private static UnityContainer container;
private static void WireUp()
{
container = new UnityContainer();
container.RegisterInstance(SomeProvider.Provider);
container.RegisterInstance(new SomeDependency());
container.RegisterType<SomeBusinessLayer>(new ContainerControlledLifetimeManager());
}
public static SomeBusinessLayer SomeBusinessLayer_Unity
{
get
{
return container.Resolve<SomeBusinessLayer>();
}
}
public static SomeBusinessLayer SomeBusinessLayer_Self()
{
var asomeProvider = SomeProvider.Provider as ASomeProvider;
if (asomeProvider != null && asomeProvider.ADependency == null)
asomeProvider.ADependency = new ADependency();
return new SomeBusinessLayer(SomeProvider.Provider);
}
}
时,SomeBusinessLayer
的依赖关系someProvider
为null。
ADependency
var someBusinessLayer = BusinessLayerFactory.SomeBusinessLayer_Unity;
是((ASomeProvider)someBusinessLayer.someProvider).ADependency
。
原因是Provider模式使用辅助方法null
来实例化默认提供程序,而不是通过Unity的ProvidersHelper.InstantiateProvider(ProviderSettings providerSettings, Type type)
方法。
我可以考虑在没有Unity的情况下执行此操作,如Resolve<T>()
所示,我SomeBusinessLayer_Self
ADependency
null
,但只是想知道Unity是否以及如何处理此问题。
方法注射或Ctor注射对我来说没问题。
如何解决此问题并使Unity和提供程序模式协同工作?我使用Unity的主要原因是在工厂中连接对象。
我没有使用MVC。
更新
解决此问题:。帽子提示到@seth-flowers
如果没有明确的演员container.BuildUp<ASomeProvider>(aSomeProvider)
,我无法找到方法。
container.RegisterInstance(new SomeDependency());
//this does not build up the object with dependency
container.BuildUp(SomeProvider.Provider);
//this works and does build up
var aSomeProvider = SomeProvider.Provider as ASomeProvider;
if(aSomeProvider != null)
container.BuildUp<ASomeProvider>(aSomeProvider);
//compile error
container.BuildUp<ASomeProvider>(SomeProvider.Provider);
container.RegisterInstance(SomeProvider.Provider);
container.RegisterType<SomeBusinessService>(new ContainerControlledLifetimeManager());
答案 0 :(得分:1)
您是否无法在BusinessLayerFactory.WireUp
方法中使用UnityContainer.BuildUp,以充实SomeProvider.Provider
实例上的依赖关系?您的对象仍将通过您的提供程序实现构建,但将通过统一注入依赖项。
例如:
private static void WireUp()
{
container = new UnityContainer();
container.RegisterInstance(SomeProvider.Provider);
container.RegisterInstance(new SomeDependency());
container.RegisterType<SomeBusinessLayer>(
new ContainerControlledLifetimeManager());
container.BuildUp<ASomeProvider>(SomeProvider.Provider as ASomeProvider);
}
BuildUp的文档声明如下:
当您不控制构造时,此方法很有用 实例(例如,通过XAML创建的ASP.NET页面或对象)但是 你仍然希望进行属性和其他注射。