如何创建通用工厂?

2024-01-15

我正在开发一个 Webmethod 集合的客户端(Silverlight)接口。我试图避免为每个网络方法编写任何自定义代码。所以我创建了一个ServiceCall<TResult>处理每个电话,TResult指定服务的返回类型(我使用XmlSerializer创建返回的实例)。客户端类公开了一个与每个 webmethod 匹配的函数,该函数所要做的就是创建一个新的实例ServiceCall<TResult>,与TResult指定为方法的预期返回类型。 这效果很好。

我也在使用Ninject http://ninject.org/(依赖注入器)尝试保持一切独立。 Ninject 支持开放泛型,这非常适合我的ServiceCall<TResult>.

但这也意味着我正在注入对 Ninject 容器的引用。这隐藏了对ServiceCall<TResult>被绑定到容器上。所以我想注入一个工厂来创建我的ServiceCall<TResult>实例。这并不棘手,但我想让它成为一个通用的通用工厂。意思是我想要类似的东西Factory<T<>>这会有一个方法public T<TU> Createinstance<TU>().

但我不知道如何使用本身就是开放泛型的类型参数创建泛型类。

在.Net 中是否有可能? - 或者我必须创建一个特定的服务调用工厂吗?

Edit:我正在使用依赖项的接口,但不需要将它们混合到此处的问题中,因此我将其编辑为问题。

回复蒂姆维:使用依赖注入 (DI) 的常见方法是将接口绑定到您的实现,只有容器知道这些绑定。然后,您可以针对接口进行编码。这带来了很多优势。我在这里无法提及的更多。
无论如何,它也排除了静态类(因为这将是对特定类的依赖)。相反,我将指示容器(在本例中为 Ninject)始终以类似单例的行为为工厂接口提供相同的实例。
这排除了public static class Factory<T>选项,因为它是静态的,如果它不是静态的,我现在需要使用我要使用的每种类型的 T,这在某种程度上违背了拥有泛型类的目的。
建议使用具有“完全通用”方法的非通用类(如我传入ServiceCall<MyResult>而不仅仅是MyResult),或多或少就是我现在正在做的事情(减去静态类部分)。 Ninject 容器有一个 Get 方法,其工作方式与您的第二个建议类似。
这个问题有两部分;首先,它使我的代码直接依赖于一个容器(Ninject),但这对我来说并不是一个大问题。让我恼火的是,如果你从外部看我的客户端,你只会看到对 Ninject 的依赖。在运行 try to make a call 之前,您不会知道客户端需要使用 Ninject 注册的 ServiceCall 实现才能工作。
但如果 Client 构造函数采用 Factory> 类型的参数,那么它会更清晰。

无论如何,我认为这将是一个常见问题,因此要么有一个常见的解决方案,要么这不是一个常见问题,而我正在尝试做一些愚蠢的事情;) 我仍然不太喜欢依赖注入,所以情况很可能就是这样。


这是你想要的:通用工厂模式 http://www.robertsindall.co.uk/blog/generic-factory-pattern-open-closed-principle/

namespace GenericFactoryPatternTestApp
{
    public class Factory< T >
    {
        private readonly Dictionary< string, Type > _factoryDictionary = new Dictionary< string, Type >();

        public Factory()
        {    
            Type[] types = Assembly.GetAssembly(typeof (T)).GetTypes();

            foreach (Type type in types)
            {
                if (!typeof (T).IsAssignableFrom(type) || type == typeof (T))
                {
                    // Incorrect type
                    continue;
                }

                // Add the type
                _factoryDictionary.Add(type.Name, type);
            }
        }

        public T Create< V >(params object[] args)
        {
            return (T) Activator.CreateInstance(_factoryDictionary[typeof (V).Name], args);
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何创建通用工厂? 的相关文章

  • 在 Xamarin Android 中将图像从 URL 异步加载到 ImageView 中

    我有一个包含多个项目的 ListView 列表中的每个项目都应该有一个与之关联的图像 我创建了一个数组适配器来保存每个列表项并具有我希望加载的图像的 url 我正在尝试使用 Web 请求异步加载图像 并设置图像并在加载后在视图中更新它 但视
  • C++ 求二维数组每一行的最大值

    我已经设法用这个找到我的二维数组的每一行的最小值 void findLowest int A Cm int n int m int min A 0 0 for int i 0 i lt n i for int j 0 j lt m j if
  • 如何在没有 Control.Invoke() 的情况下从后台线程修改控件属性

    最近 我们遇到了一些旧版 WinForms 应用程序 我们需要更新一些新功能 在专家测试该应用程序时 发现一些旧功能被破坏 无效的跨线程操作 现在 在您认为我是新手之前 我确实有一些 Windows 窗体应用程序的经验 我不是专家 但我认为
  • 嵌入式系统中的malloc [重复]

    这个问题在这里已经有答案了 我正在使用嵌入式系统 该应用程序在 AT91SAMxxxx 和 cortex m3 lpc17xxx 上运行 我正在研究动态内存分配 因为它会极大地改变应用程序的外观 并给我更多的力量 我认为我唯一真正的路线是为
  • 使用 Microsoft Graph API 订阅 Outlook 推送通知时出现 400 错误请求错误

    我正在尝试使用 Microsoft Graph API 创建订阅以通过推送通知获取 Outlook 电子邮件 mentions 我在用本文档 https learn microsoft com en us graph api subscri
  • 跨多个控件共享事件处理程序

    在我用 C 编写的 Windows 窗体应用程序中 我有一堆按钮 当用户的鼠标悬停在按钮上时 我希望按钮的边框发生变化 目前我有以下多个实例 每个按钮一个副本 private void btnStopServer MouseEnter ob
  • c# Asp.NET MVC 使用FileStreamResult下载excel文件

    我需要构建一个方法 它将接收模型 从中构建excel 构建和接收部分完成没有问题 然后使用内存流导出 让用户下载它 不将其保存在服务器上 我是 ASP NET 和 MVC 的新手 所以我找到了指南并将其构建为教程项目 public File
  • 当 Cortex-M3 出现硬故障时如何保留堆栈跟踪?

    使用以下设置 基于 Cortex M3 的 C gcc arm 交叉工具链 https launchpad net gcc arm embedded 使用 C 和 C FreeRtos 7 5 3 日食月神 Segger Jlink 与 J
  • 基于范围的 for 循环中的未命名循环变量?

    有没有什么方法可以不在基于范围的 for 循环中 使用 循环变量 同时也避免编译器发出有关未使用它的警告 对于上下文 我正在尝试执行以下操作 我启用了 将警告视为错误 并且我不想进行像通过在某处毫无意义地提及变量来强制 使用 变量这样的黑客
  • 在 ASP.Net Core 2.0 中导出到 Excel

    我曾经使用下面的代码在 ASP NET MVC 中将数据导出到 Excel Response AppendHeader content disposition attachment filename ExportedHtml xls Res
  • Windows 窗体不会在调试模式下显示

    我最近升级到 VS 2012 我有一组在 VS 2010 中编码的 UI 测试 我试图在 VS 2012 中启动它们 我有一个 Windows 窗体 在开始时显示使用 AssemblyInitialize 属性运行测试 我使用此表单允许用户
  • 如何在 Team Foundation 上强制发表有意义的签入评论?

    我有一个开发团队有一个坏习惯 他们写道poor签入评论 当我们必须在团队基础上查看文件的历史记录时 这使得它成为一场噩梦 我已经启用了变更集评论政策 这样他们甚至可以在签到时留下评论 否则他们不会 我们就团队的工作质量进行了一些讨论 他们很
  • 使用 LINQ 查找列表中特定类型的第一个元素

    使用 LINQ 和 C 在元素列表中查找特定类型的第一个项目的最短表示法是什么 var first yourCollection OfType
  • 线程、进程和 Application.Exit()

    我的应用程序由主消息循环 GUI 和线程 Task Factory 组成 在线程中我调用一些第三方应用程序var p new Process 但是当我调用Application Exit 在消息循环中 我可以看到在线程中启动的进程仍在内存中
  • 我的 strlcpy 版本

    海湾合作委员会 4 4 4 c89 我的程序做了很多字符串处理 我不想使用 strncpy 因为它不会终止 我不能使用 strlcpy 因为它不可移植 只是几个问题 我怎样才能让我的函数正常运行 以确保它完全安全稳定 单元测试 这对于生产来
  • AccessViolationException 未处理

    我正在尝试使用史蒂夫 桑德森的博客文章 http blog stevensanderson com 2010 01 28 editing a variable length list aspnet mvc 2 style 为了在我的 ASP
  • 检查 url 是否指向文件或页面

    我们需要以下内容 如果文件确实是文件 则从 URL 下载该文件 否则 如果它是一个页面 则什么也不做 举个简单的例子 我有以下命令来下载文件 My Computer Network DownloadFile http www wired c
  • 如何构建印度尼西亚电话号码正则表达式

    这些是一些印度尼西亚的电话号码 08xxxxxxxxx 至少包含 11 个字符长度 08xxxxxxxxxxx 始终以 08 开头 我发现这个很有用 Regex regex new Regex 08 0 9 0 9 0 9 0 9 0 9
  • GDK3/GTK3窗口更新的精确定时

    我有一个使用 GTK 用 C 语言编写的应用程序 尽管该语言对于这个问题可能并不重要 这个应用程序有全屏gtk window与单个gtk drawing area 对于绘图区域 我已经通过注册了一个刻度回调gtk widget add ti
  • 不同类型的指针可以互相分配吗?

    考虑到 T1 p1 T2 p2 我们可以将 p1 分配给 p2 或反之亦然吗 如果是这样 是否可以不使用强制转换来完成 或者我们必须使用强制转换 首先 让我们考虑不进行强制转换的分配 C 2018 6 5 16 1 1 列出了简单赋值的约束

随机推荐