当Provider实现具有依赖关系时,如何使用Unity与Provider模式

时间:2012-10-31 17:42:21

标签: c# dependencies unity-container provider

我正在使用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());

1 个答案:

答案 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页面或对象)但是   你仍然希望进行属性和其他注射。