Factories


Providers are just one of the two constructs that are used to allow an application block to be decoupled from any specific implementation. To truly be decoupled from a provider's implementation, a software factory should exist in the application block so that it allows providers to be created and used in a way that a consumer of the core functionality needs to know very little, if anything, about a particular provider. Listing 9.1 showed an example of this; a DataMappingsFactory was used to create and return a class that implemented the IDataMappingProvider interface. If the application block did not use the factory, but instead just initialized an instance of a class that implements the IDataMappingProvider interface, then the application block would be tightly coupled to that provider. The combination of the factory and the providers are what give an application block its ability to be decoupled from any single implementation.

The factories in the Enterprise Library application blocks subscribe to the Plugin[3] design pattern to create providers. By using this design pattern, neither applications nor application blocks require specific implementation information about the provider. Furthermore, specific implementations for each provider are constructed according to the configuration settings for that provider.

[3] Martin Fowler, Patterns of Enterprise Application Architecture, pp. 499503. Addison-Wesley, 2002.

The Configuration Application Block contains an abstract base class named ProviderFactory that is intended to serve as the base class for any specific application block's provider factories. The ProviderFactory takes most of the hard work out of creating a factory to instantiate configurable providers away from any derived class.

Each of the previous chapters have shown how an application block uses its provider factory to create a specific implementation of a provider. Most of the application blocks actually included two factory classes; one was the provider factory that creates a specific provider, and the other was a class that wrapped around the provider factory with static methods so a consumer doesn't need to directly instantiate a provider factory to obtain a provider. Also, each of the provider factories discussed generally contained two methods for creating a provider: one for creating the default provider as specified by the configuration settings and one for creating a named provider.

Listing 9.3 shows the code for the DataMappingsProviderFactory.

Listing 9.3. The DataMappingsProviderFactory Class

[C#] public class DataMappingsProviderFactory : ProviderFactory {     public DataMappingsProviderFactory() :          this(ConfigurationManager.GetCurrentContext())     {     }     public DataMappingsProviderFactory(ConfigurationContext context):          base("DataMappings Factory", context,          typeof(IDataMappingProvider))     {     }     public IDataMappingProvider GetDataMappingProvider(string name)     {          return (IDataMappingProvider)base.CreateInstance(name);     }     public IDataMappingProvider GetDataMappingProvider()     {          return (IDataMappingProvider)base.CreateDefaultInstance();     }     protected override string GetDefaultInstanceName()      {          DataMappingsConfigurationView view =               (DataMappingsConfigurationView)               CreateConfigurationView();          return view.GetDefaultDataMappingProviderDataName();      }      protected override ConfigurationView CreateConfigurationView()      {          return new               DataMappingsConfigurationView(ConfigurationContext);      }     protected override Type GetConfigurationType(string instanceName)     {          DataMappingsConfigurationView view =               (DataMappingsConfigurationView)               CreateConfigurationView();          DataMappingProviderData dataMappingProviderData =               view.GetDataMappingProviderData(instanceName);          return GetType(dataMappingProviderData.TypeName);     } } [Visual Basic] Public Class DataMappingsProviderFactory : Inherits ProviderFactory     Public Sub New()          Me.New(ConfigurationManager.GetCurrentContext())     End Sub     Public Sub New(ByVal context As ConfigurationContext)          MyBase.New("DataMappings Factory", context, _               GetType(IDataMappingProvider))     End Sub     Public Function GetDataMappingProvider(ByVal name As String) _               As IDataMappingProvider          Return CType(MyBase.CreateInstance(name), _               IDataMappingProvider)     End Function     Public Function GetDataMappingProvider() As IDataMappingProvider          Return CType(MyBase.CreateDefaultInstance(), _               IDataMappingProvider)     End Function     Protected Overrides Function GetDefaultInstanceName() As String               Dim view As DataMappingsConfigurationView = _                    CType(CreateConfigurationView(), _                    DataMappingsConfigurationView)               Return view.GetDefaultDataMappingProviderDataName()     End Function     Protected Overrides Function CreateConfigurationView() _                    As ConfigurationView               Return New _               DataMappingsConfigurationView(ConfigurationContext)     End Function     Protected Overrides Function GetConfigurationType _                    (ByVal instanceName As String) As Type               Dim view As DataMappingsConfigurationView = _                    CType(CreateConfigurationView(), _                    DataMappingsConfigurationView)               Dim dataMappingProviderData As _                    DataMappingProviderData = _                    view.GetDataMappingProviderData(instanceName)               Return GetType(dataMappingProviderData.TypeName)     End Function End Class

The important point to understand from this listing is that by deriving from the abstract ProviderFactory class, a concrete provider factory doesn't need to contain any code for reading configuration data and creating providers via reflection. This is accomplished in the base class. The concrete provider factory only needs to be able to return a ConfigurationView that contains the configuration settings for the provider and supplies methods for returning the providers to a consumer of the factory. Once the provider factory has been developed, the other factory can be written to encapsulate the provider factory and supply static methods for creating the default provider and a named provider.

In the Enterprise Library application blocks, this factory generally has the same name as the provider factory but without the word Provider in it. Thus, I have created a DataMappingsFactory that encapsulates the DataMappingsProviderFactory and exposes an overloaded method for obtaining either the default DataMappingProvider or a named DataMappingProvider. Figure 9.3 shows the relationship between these two factory classes and the DataMappingsConfigurationView.

Figure 9.3. Factory Classes in the Data Mapping Application Block





Fenster Effective Use of Microsoft Enterprise Library(c) Building Blocks for Creating Enterprise Applications and Services 2006
Effective Use of Microsoft Enterprise Library: Building Blocks for Creating Enterprise Applications and Services
ISBN: 0321334213
EAN: 2147483647
Year: 2004
Pages: 103
Authors: Len Fenster

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net