我能全局设置接口实现吗? [英] Can I globally set the interface implementation to use?

查看:254
本文介绍了我能全局设置接口实现吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个接口:

  public interface IHHSDBUtils 
{
void SetupDB();

bool TableExists(string tableName);
。 。 。

...有多个实施者:

  public class SQLiteHHSDBUtils:IHHSDBUtils 
public class SQCEHHSDBUtils:IHHSDBUtils
public class FlatfileHHSDBUtils:IHHSDBUtils
public class TestHHSDBUtils:IHHSDBUtils

我希望能够指定从全局访问点使用哪个实现者,例如:

  public static class HHSConsts 
{
public static IHHSDBUtils hhsdbutil = SQLiteHHSDBUtils;

...然后在应用程序的任何位置调用它:

  private HHSDBUtils hhsdbutils {get;组; } 
。 。 。
hhsdbutils = new HHSConsts.hhsdbutil;
hhsdbutils.SetupDB();

这可能吗?我得到了,''SQLiteHHSDBUtils'是一个'type',但是像'变量'一样被用于hhsdbutil的上面。 p>您可以通过为每种类型创建一个枚举来实现poormans Factory实现,并有一个静态工厂方法为您创建类型。我尽可能地接近您当前的代码片段。

  public enum HHSDBUtilsTypes 
{
Sqllite,
SQCE,
Flatfile,
Test
}

public static class HHSConsts
{
private const string implementation = HHSDBUtilsTypes.Sqllite; //您可以从配置文件中读取它

public静态IHHSDBUtils GetUtils()
{
IHHSDBUtils impl;
switch(实现)
{
case HHSDBUtilsTypes.Sqllite:
impl = new SQLiteHHSDBUtils();
break;
case HHSDBUtilsTypes.SQCE:
impl = new SQCEHHSDBUtils();
休息;
case HHSDBUtilsTypes.Sqllite:
impl = new FlatfileHHSDBUtils();
休息;
默认值:
impl = new TestHHSDBUtils();
休息;
}
返回impl;
}
}

你可以像这样使用它:

  private IHHSDBUtils hhsdbutils {get;组; } 
//。 。 。
hhsdbutils = HHSConsts.GetUtils();
hhsdbutils.SetupDB();

另一种选择是使用 Activator.CreateInstance

  const string fulltypename =Your.Namespace.SQLiteHHSDBUtils; //或从配置文件读取; 
hhsdbutils =(HHSDBUtils)Activator.CreateInstance(null,fulltypename).Unwrap();

确保测试和衡量性能,特别是如果您需要经常通过任何类型实例化许多类型

如果您想要更多控制,请使用依赖注入/控制反转框架,如:



请注意,所有这些框架都带来了自己强大的功能,但也增加了复杂性。如果您觉得必须选择一个框架,那么需要将可维护性和可学习性作为一项主要要求。

以下是一些额外的关于DI的文档


I have an interface:

public interface IHHSDBUtils
{
    void SetupDB();

    bool TableExists(string tableName);
    . . .

...that has multiple implementers:

public class SQLiteHHSDBUtils : IHHSDBUtils
public class SQCEHHSDBUtils : IHHSDBUtils
public class FlatfileHHSDBUtils : IHHSDBUtils
public class TestHHSDBUtils : IHHSDBUtils

I want to be able to specify which implementer is going to be used from a globally accessible spot, such as:

public static class HHSConsts
{
    public static IHHSDBUtils hhsdbutil = SQLiteHHSDBUtils;

...and then call it like so from anywhere in the app:

private HHSDBUtils hhsdbutils { get; set; }
. . .
hhsdbutils = new HHSConsts.hhsdbutil;
hhsdbutils.SetupDB();

Is this possible? I get, "'SQLiteHHSDBUtils' is a 'type' but is used like a 'variable' with its assignment to hhsdbutil above.

解决方案

You could do a poormans Factory implementation by creating an enum for each type and have a static factory method that creates the type for you. I stay as close to your current code snippets as possible.

public enum HHSDBUtilsTypes 
{
    Sqllite,
    SQCE,
    Flatfile,
    Test
}

public static class HHSConsts
{
    private const string implementation = HHSDBUtilsTypes.Sqllite; // you might read this from the config file

    public static IHHSDBUtils GetUtils()
    {
         IHHSDBUtils impl;
         switch(implementation)
         {
            case HHSDBUtilsTypes.Sqllite:
               impl = new SQLiteHHSDBUtils();
            break;
            case HHSDBUtilsTypes.SQCE:
               impl = new SQCEHHSDBUtils();
            break;
            case HHSDBUtilsTypes.Sqllite:
               impl = new FlatfileHHSDBUtils();
            break;
            default:
               impl = new TestHHSDBUtils();
            break;
         }
         return impl;
    }
}

And you would use it like so:

private IHHSDBUtils hhsdbutils { get; set; }
//. . .
hhsdbutils = HHSConsts.GetUtils();
hhsdbutils.SetupDB();

An other option is to use Activator.CreateInstance.

 const string fulltypename = "Your.Namespace.SQLiteHHSDBUtils"; // or read from config;
 hhsdbutils = (HHSDBUtils) Activator.CreateInstance(null, fulltypename).Unwrap();

Make sure to test and measure performance, specially if you need to instantiate a lot of types often via any of these methods.

If you want more control use a Dependency Injection/Inversion of Control framework like:

Be aware though that all of these frameworks bring in their own powerfull features but also added complexity. If you feel you have to select a framework take maintainability and learnability as a dominant requirement.

Here is some extra documentation on DI

这篇关于我能全局设置接口实现吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆