如何根据某些标志/参数指示返回接口的哪个实现?
在具有多个支持数据库的分布式应用程序中,我们正在寻找更好的方法来处理数据库连接的创建。例如,假设您的系统背后有三个数据库:
- 业务数据(订单、产品、 类别等)
- 元数据(有关的数据 业务数据的结构)
- 用户数据(用户偏好,保存 工件等)
数据的详细信息并不重要......它只是三个数据库。在您的应用程序中,您希望获得与这三个对象的连接并返回 IDbConnection 实现。用于用户数据的实现可能与用于业务数据的实现略有不同。等等。每个连接字符串都在配置文件中。
因此,我们研究了几种方法,包括:
具有多个方法的工厂
class ConnectionFactory {
public static IDbConnection CreateBusinessDataConnection()
{
//
}
public static IDbConnection CreateMetadataConnection()
{
//
}
public static IDbConnection CreateUserDataConnection()
{
//
}
}
...不过,在本示例中,我们也可能返回特定的实现,而不是返回 IDbConnection 引用。缺点是,如果以后不更改消费者代码,我们就无法更改所使用的连接类型。
具有单一方法的工厂
在这种情况下,我们使用单一方法并传入一些值(可能是枚举)来指示我们想要的连接类型:
enum DbConnectionType { BusinessData, Metadata, UserData }
class ConnectionFactory {
public static IDbConnection CreateDataConnection(DbConnectionType connType)
{
// look at connType and probably use a switch statement to create
// the connection for that type.
}
}
这些都有优点和缺点......为了添加到混合中,我们最近开始在项目中使用 Microsoft 的 Unity IoC 容器。看起来这在这里可能很有价值,但我们的理解还处于早期阶段。从表面上看,它看起来对我们没有帮助,因为我们没有注册具体类型。
container.Register(IDbConnection, [ which of the three implementations ? ]);
相反,它更像是我们在说“当我请求 IDbContainer 并为您提供此枚举值时,请返回 IdbConnection 的此实现。”我们尚未找到一种方法来做到这一点在 Unity 中(但同样,它对我们来说仍然是新的,我们正在研究示例)。
想法?
In a distributed application that has multiple databases that support it, we're looking for better ways to handle the creation of the database connections. For example, suppose your system has three database behind it:
- Business Data (orders, products,
categories, etc) - Metadata (data about
the structure of the business data) - User Data (user preferences, saved
artifacts, etc)
The details of the data aren't important... it's simply three databases. Throughout your app, you want to get connections to these three and return an IDbConnection implementation. The implementation used for User Data may differ slightly than the one used for Business Data. and so on. Connection strings for each are in a config file.
So we've looked at a couple of approaches, including:
Factory with Multiple Methods
class ConnectionFactory {
public static IDbConnection CreateBusinessDataConnection()
{
//
}
public static IDbConnection CreateMetadataConnection()
{
//
}
public static IDbConnection CreateUserDataConnection()
{
//
}
}
... in this example, though, we might just as well return a specific implementation rather than the IDbConnection reference. The downside being that we couldn't change the type of connection used without changing the consumer code later.
Factory with Single Method
In this case, we use a single method and pass in some value (likely an enum) to indicate what connection type we want:
enum DbConnectionType { BusinessData, Metadata, UserData }
class ConnectionFactory {
public static IDbConnection CreateDataConnection(DbConnectionType connType)
{
// look at connType and probably use a switch statement to create
// the connection for that type.
}
}
These both have upsides and downsides... to add to the mix, we've recently started using the Unity IoC container from Microsoft in the project. It seems like this might be valuable here, but it's early in our understanding. On the surface, it doesn't look like it helps us because we're not registering a concrete type.
container.Register(IDbConnection, [ which of the three implementations ? ]);
Instead, it's more like we're saying "When I request an IDbContainer and I also provide you with this enum value, please return THIS implementation of IdbConnection." We've yet to find a way to do that in Unity (but again, it's still new to us and we're working through samples).
Thoughts?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
第二种变体对我来说看起来最好(尽管第一种变体几乎没有什么不同)。这样做的优点是,唯一需要知道或考虑要连接到哪个数据库的代码是调用
ConnectionFactory
的代码 - 其他所有代码都可以使用通用的IDBConnection
代码>接口。The second variant looks best to me (although the first is barely different). The advantage of this is that the only code that has to know or think about which database to connect to is the code that calls the
ConnectionFactory
--everything else can just use the genericIDBConnection
interface.假设应用程序的特定实例将为每种数据库类型使用相同类型的连接(即每个应用程序一个提供程序),您可以为每个不同的连接提供程序实现类并使 ConnectionFactory 成为一个接口。
然后在 Unity 中将每个连接工厂实现注册为命名类型。
当应用程序解析连接工厂时,您可以将提供程序定义为配置文件中的设置,这样,如果以后更改提供程序,则无需重新编码。
Assuming that a particular instance of your application will be using the same type of connection for each of the database types (i.e. one provider per application), you can implement classes for each of the different connection providers and make the ConnectionFactory an interface.
Then register each of the connection factory implementations as a Named type in Unity.
When the application goes to resolve the connection factory, you can have the provider defined as a setting in the configuration file, that way no recoding is necessary if they later change providers.
将第一个设计的方法放入第二个设计的方法主体中。然后,您实现工厂设计模式的一个实例。
Put the methods of the first design into the body of the method of the second design. Then, you implement an instance of the Factory design pattern.