【问题标题】:Create a Generic Service Factory创建通用服务工厂
【发布时间】:2015-08-10 10:24:44
【问题描述】:

我正在尝试创建类似于 2 层架构的东西,其中服务层实例始终需要由工厂在服务层中创建。我希望该服务工厂是通用的并返回一个接口。我做过这样的事情:

// service base interface
namespace SimpleFW.Services
{
    public interface IServiceBase
    {
        void Get();
        void Create();
        void Update();
        void Delete();
    }
}

创建以下代码以添加每个服务的自定义功能:

// interface for the custom implementation
namespace SimpleFW.Services
{
    public interface ISimpleService : IServiceBase
    {
        void CustomMethod();
    }
}

这是服务的实现方式

// implementation of the service
namespace SimpleFW.Services
{
    public class SimpleService : ISimpleService
    {
        public void CustomMethod()
        {
            Debug.Write("CustomMethod Method Called.");
        }

        public void Get()
        {
            Debug.Write("Get Method Called.");
        }

        public void Create()
        {
            Debug.Write("Create Method Called.");
        }

        public void Update()
        {
            Debug.Write("Update Method Called.");
        }

        public void Delete()
        {
            Debug.Write("Delete Method Called.");
        }
    }
}

这是一个将创建服务实例的通用工厂:

// service factory
namespace SimpleFW.Services
{
    public class ServiceFactory
    {
        public static IServiceBase GetService<T>() where T : IServiceBase, new()
        {
            return new T();
        }
    }
}

这是单独程序集中的服务客户端

// service client in separate assembly
namespace SimpleFW.Client
{
    class Program
    {
        static void Main(string[] args)
        {
            IServiceBase service = ServiceFactory.GetService<SimpleService>();

            service.Get(); // should be callable from within the same assembly not from client assembly
            service.Create(); // should be callable from within the same assembly not from client assembly
            service.Update(); // should be callable from within the same assembly not from client assembly
            service.Delete(); // should be callable from within the same assembly not from client assembly

            ((ISimpleService)service).CustomMethod(); // this is fine. I should be able to cast and call the methods like this

            SimpleService serObject = new SimpleService(); // how to make this impossible
        }
    }
}

虽然我在任何我关心的地方都写了代码旁边的 cmets,但问题仍然存在:

  • 如何对外部程序集隐藏 IServiceBase 接口的实现?
  • 如何将 SimpleService 类的构造仅限于 Factory,以便始终需要外部程序集从通用服务类型的工厂调用 GetService 方法?

一些解决方案(也许):这是我要做的:

SimpleService 将始终显式地实现接口,如下所示:

// implementation of the service
namespace SimpleFW.Services
{
    public class SimpleService : ISimpleService
    {
        public void ISimpleService.CustomMethod()
        {
            Debug.Write("CustomMethod Method Called.");
        }

        public void IServiceBase.Get()
        {
            Debug.Write("Get Method Called.");
        }

        public void IServiceBase.Create()
        {
            Debug.Write("Create Method Called.");
        }

        public void IServiceBase.Update()
        {
            Debug.Write("Update Method Called.");
        }

        public void IServiceBase.Delete()
        {
            Debug.Write("Delete Method Called.");
        }
    }
}

通过进行上述更改不会阻止服务层的消费者创建 SimpleService 的实例,但他们将无法直接调用任何已实现的方法。他们将只能访问该服务的自定义公共方法。

【问题讨论】:

    标签: c# .net generics service factory


    【解决方案1】:

    如何隐藏 IServiceBase 接口的实现 外部程序集?

    使用内部访问权限modifier

    如何将 SimpleService 类的构造限制为 工厂只有这样,外部组件总是需要调用 通用服务类型工厂的GetService方法?

    内部访问修饰符将解决您的 SimpleService 问题。

    对于您的工厂,我建议使用 Enum 来创建您的服务。

        public enum ServiceType
        {
           SimpleService,
           .
           .
        }
    
        // For naming convention use CreateService
        IServiceBase service = ServiceFactory.GetService(ServiceType.SimpleService);
    
    
       public class ServiceFactory
       {
          public static T GetService(enum type)
          {
             // create you service here         
          }
       }
    

    【讨论】:

    • 那么你的意思是没有为什么要让它成为泛型类型类?
    • GetService 之后你没有看到 T 还是通用的。
    • 你在跟我开玩笑吗……为什么全班都知道T?猜你错过了什么。
    【解决方案2】:
    • 要隐藏 IServiceBase 的实现,您可以将基接口放在单独的程序集中而不是实现:

    assembly SimpleFW.Services.Core -&gt; IServiceBase interface

    assembly SimpleFW.Services.Implementation -&gt; SimpleService class

    请注意,在实际必须编写整个应用程序的程序集中,您必须在服务实现中引用程序集。因此,该服务的实现将在该程序集中可见。但其他程序集只能使用Services.Core 程序集并使用对接口进行编程

    • 您可以使用内部构造函数来限制 SimpleService 类的构造。

    【讨论】:

    • 对不起@arkadiusz-k 我不是在寻找你的建议。可能我需要更清楚地了解这个问题。让我准备一个更好的问题并在这里进行编辑。不过现在很忙会回来的...
    猜你喜欢
    • 2020-06-03
    • 2012-02-05
    • 1970-01-01
    • 1970-01-01
    • 2022-01-27
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-02-28
    相关资源
    最近更新 更多