- c - 在位数组中找到第一个零
- linux - Unix 显示有关匹配两种模式之一的文件的信息
- 正则表达式替换多个文件
- linux - 隐藏来自 xtrace 的命令
我在这里伤了我的脑子。
一些背景:
我在多层应用程序中有多个服务。其中一些是短暂的(应该与 using
一起使用)而有些则不是(所以我只是将它们注入(inject)到我想要的任何类中并直接使用)。我的客户端代码有不同的数据接口(interface)和随机 using
关键字。
出于某些原因(主要是为了科学),我决定对其进行一些重构。我做了一个通用的 DataServiceAdapter<>
我使用的每个服务都应该关闭的类,这个通用类封装了using
来自客户端的逻辑。
DataServiceAdapter
看起来像这样(简短的工作示例 here on dotnetfiddle)
public class DataServiceAdapter<TService> : IDataService
where TService : IDataService, new()
{
private readonly TService _service;
private readonly Func<Func<TService, dynamic>, dynamic> _run;
public DataServiceAdapter()
{
if (typeof(IDisposable).IsAssignableFrom(typeof(TService)))
{
_run = RunWithUsing;
}
else
{
_service = new TService();
_run = RunWithoutUsing;
}
}
public bool Foo()
{
return _run(x => x.Foo());
}
public int Bar(string arg)
{
return _run(x => x.Bar(arg));
}
private dynamic RunWithUsing(Func<TService, dynamic> func)
{
using (var service = (IDisposable) new TService())
{
return func((TService)service);
}
}
private dynamic RunWithoutUsing(Func<TService, dynamic> func)
{
return func(_service);
}
}
public interface IDataService
{
bool Foo();
int Bar(string arg);
}
客户端应该像这样使用它:
//class variable. Get this from IoC container
private readonly IDataService _service;
//somewhere in methods
var resultData = _service.Foo(); //full static type checking
但因为我的现实版IDataService
包含我重写的几十个方法DataServiceAdapter
像这样(仅更改,dotnetfiddle link):
public class DataServiceAdapter<TService> : IDataServiceAdapter<TService>
where TService : IDataService, new()
{
public dynamic Run(Func<TService, dynamic> func)
{
return _serviceUsing(func);
}
}
public interface IDataServiceAdapter<out TService>
where TService : IDataService
{
dynamic Run(Func<TService, dynamic> func);
}
客户端现在可以使用该版本的 DataServiceAdapter
这样:
//class variable. Get this from IoC container
private readonly IDataServiceAdapter<IDataService> _service;
//somewhere in methods
var resultData = _service.Run(s => s.Foo());
由于 dynamic
,它无需静态检查即可工作
所以(我们接近质疑)我决定再次重写它(为了科学)并返回静态安全,但没有必要包装所有 IDataService
我的适配器类中的方法。
首先我写了这个delegate
:
private delegate TRes RunDelegate<TResult>(Func<TService, TResult> func);
但我无法像上面那样创建此类委托(delegate)的变量并向其传递一些我希望使用的方法。
问题:有没有什么方法可以在那里实现我的设计思想(通用服务提供者调用带有 using
的方法或没有它的方法并且具有类型安全性)?
最佳答案
您可以将运行逻辑委托(delegate)给实现 IRunner 接口(interface)的运行器类。如果您觉得有必要,您可以选择注入(inject)它。
像这样:
使用系统;
public class Program
{
public static void Main()
{
//Dependency register logic here. Choose either
//var service = new DataServiceAdapter<SpecificNotDisposableDataService>();
var service = new DataServiceAdapter<SpecificDisposableDataService>();
var client = new Client(service);
client.ClientMethod();
Console.ReadLine();
}
}
public class Client
{
private readonly IDataServiceAdapter<IDataService> _service;
public Client(IDataServiceAdapter<IDataService> service)
{
_service = service;
}
public void ClientMethod()
{
Console.WriteLine(_service.Run(s => s.Foo()));
Console.WriteLine(_service.Run(s => s.Bar("Hello")));
}
}
public class DataServiceAdapter<TService> : IDataServiceAdapter<TService>
where TService : IDataService, new()
{
private interface IRunner
{
T Run<T>(Func<TService, T> func);
}
private class WithUsing : IRunner
{
public T Run<T>(Func<TService, T> func)
{
using (var service = (IDisposable) new TService())
{
return func((TService)service);
}
}
}
private class WithoutUsing : IRunner
{
private readonly TService _service = new TService();
public T Run<T>(Func<TService, T> func)
{
return func(_service);
}
}
private readonly IRunner _runner;
public DataServiceAdapter()
{
if (typeof(IDisposable).IsAssignableFrom(typeof(TService)))
{
_runner = new WithUsing();
}
else
{
_runner = new WithoutUsing();
}
}
public T Run<T>(Func<TService, T> func)
{
return _runner.Run<T>(func);
}
}
public class SpecificDisposableDataService : IDataService, IDisposable
{
public bool Foo()
{
return true;
}
public int Bar(string arg)
{
return arg.Length;
}
public void Dispose()
{
//Dispose logic here
}
}
public class SpecificNotDisposableDataService : IDataService
{
public bool Foo()
{
return false;
}
public int Bar(string arg)
{
return arg.Length*2;
}
}
public interface IDataServiceAdapter<out TService>
where TService : IDataService
{
T Run<T>(Func<TService, T> func);
}
public interface IDataService
{
bool Foo();
int Bar(string arg);
}
这是上面的工作 dotnetfiddle:https://dotnetfiddle.net/FmNpju
这是另一个运行这两种服务的: https://dotnetfiddle.net/KxEGRB
关于c# - 通用委托(delegate)变量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31944088/
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: How to nest OR statements in JavaScript? 有没有办法做到这一点:
在 JavaScript 中有没有办法让一个变量总是等于一个变量?喜欢var1 = var2但是当var2更新,也是var1 . 例子 var var1 = document.getElementBy
我正在努力理解这代表什么 var1 = var2 == var3 我的猜测是这等同于: if (var2 == var3): var1 = var2 最佳答案 赋值 var1 = var2
这个问题已经有答案了: What does the PHP error message "Notice: Use of undefined constant" mean? (2 个回答) 已关闭 8
我在临时表中有几条记录,我想从每条记录中获取一个值并将其添加到一个变量中,例如 color | caption -------------------------------- re
如何将字符串转为变量(字符串变量--> $variable)? 或者用逗号分隔的变量列表然后转换为实际变量。 我有 2 个文件: 列名文件 行文件 我需要根据字符串匹配行文件中的整行,并根据列名文件命
我有一个我无法解决的基本 php 问题,我也想了解为什么! $upperValueCB = 10; $passNodeMatrixSource = 'CB'; $topValue= '$uppe
这可能吗? php $variable = $variable1 || $variable2? 如果 $variable1 为空则使用 $variable2 是否存在类似的东西? 最佳答案 PHP 5
在 Perl 5.20 中,for 循环似乎能够修改模块作用域的变量,但不能修改父作用域中的词法变量。 #!/usr/bin/env perl use strict; use warnings; ou
为什么这不起作用: var variable; variable = variable.concat(variable2); $('#lunk').append(variable) 我无法弄清楚这一点
根据我的理解,在32位机器上,指针的sizeof是32位(4字节),而在64位机器上,它是8字节。无论它们指向什么数据类型,它们都有固定的大小。我的计算机在 64 位上运行,但是当我打印包含 * 的大
例如: int a = 10; a += 1.5; 这运行得很完美,但是 a = a+1.5; 此作业表示类型不匹配:无法从 double 转换为 int。所以我的问题是:+= 运算符 和= 运算符
您好,我写了这个 MySQL 存储过程,但我一直收到这个语法错误 #1064 - You have an error in your SQL syntax; check the manual that
我试图在我的场景中显示特定的奖牌,这取决于你的高分是基于关卡的目标。 // Get Medal Colour if levelHighscore goalScore { sc
我必须维护相当古老的 Visual C++ 源代码的大型代码库。我发现代码如下: bIsOk = !!m_ptr->isOpen(some Parameters) bIsOk的数据类型是bool,is
我有一个从 MySQL 数据库中提取的动态产品列表。在 list 上有一个立即联系 按钮,我正在使用一个 jquery Modal 脚本,它会弹出一个表单。 我的问题是尝试将产品信息变量传递给该弹出窗
这个问题在这里已经有了答案: 关闭 10 年前。 Possible Duplicate: What is the difference between (type)value and type(va
jQuery Core Style Guidelines建议两种不同的方法来检查变量是否已定义。 全局变量:typeof variable === "undefined" 局部变量:variable
这个问题已经有答案了: 已关闭11 年前。 Possible Duplicate: “Variable” Variables in Javascript? 我想肯定有一种方法可以在 JavaScrip
在语句中使用多重赋值有什么优点或缺点吗?在简单的例子中 var1 = var2 = true; 赋值是从右到左的(我相信 C# 中的所有赋值都是如此,而且可能是 Java,尽管我没有检查后者)。但是,
我是一名优秀的程序员,十分优秀!