Tag: 设计

将流传递给多个方法可以吗?

我有一个接口定义为: public interface IClientFileImporter { bool CanImport(Stream stream); int Import(Stream stream); } 我们的想法是获取任何文件流并通过此接口的一系列实现来运行它,以确定哪个文件流应该处理该文件。 一些实现可能寻找某个标题行,而其他实现可能寻找某个字节序列等… 我的问题是,只要我从不关闭它就可以像这样传递流吗? 如有必要,每种方法都必须负责将流重置到位置0,但是除了线程安全之外还有其他任何潜在的问题吗? 这段代码真的闻起来,IMO,但我不确定一个更好的方法来做到这一点。

“阻止”直到满足某些条件的最佳方法

我想创建一些以通用方式使用的方法,它是否会阻塞(除非某个超时到期),直到满足给定条件。 代码中的用法类似于: WaitUntil( condition ); 我尝试使用While(..)循环实现它,但这似乎是浪费。 在当前的实现中,我正在初始化一个在TIMEOUT到期的“一次性”计时器。 我正在运行一个while循环,并检查计时器是否已超时,如果有,则抛出exception。 有没有简单而有效的技术来实现这种方法?

Winforms应用程序设计

考虑您在一个项目中使用winform应用程序,在其他项目中使用业务逻辑。 UI工作人员的项目参考了业务逻辑项目。 在主winform的构建过程中,逻辑单元的实例的分配应该是gui背后的大脑并且位于业务逻辑项目中。 对它的引用保存在Main Winform中。 假设我对gui有更新,我可以通过业务逻辑实例级别调用的方法的返回值来获取它。 这是一个糟糕的设计,你会如何改进它?(例子将不胜感激)

包装可能瞬态对象的惯用方法

我正在为控制pulseaudio声音服务器的C库编写一些C#绑定,我不确定如何惯用绑定一些暴露的潜在瞬态对象:特别是接收器。 pulseaudio具有音频接收器的概念 – 给定音频流的硬件正在播放。 这自然会映射到一个Sink类,具有一些明显的属性 – 音量等。 问题是热插拔 – 音频硬件可以在运行时进出,因此这样的Sink对象可能最终成为僵尸引用不存在的硬件,并且对它们执行的所有操作都将失败。 更糟糕的是,C库没有为接收器提供唯一的句柄,因此一系列热插拔事件可能会改变给定Sink实例实际控制的硬件,而无需代码注意。 这两个问题都闻到了。 我想提供一些Sink抽象,但我不确定如何避免这些问题。 处于类似情况的其他人如何处理这类问题? 编辑:在C库中,您似乎只希望在查询接收器和尝试更改其属性之间不会发生热插拔事件。 通过索引在API中标识接收器,但这不稳定。 每个接收器还有一个标识符字符串,我认为这是唯一的,至少对于每次运行。 有一个API可以对各种有趣的事件进行回调,例如hotplug,因此可以将每个Sink到那个,并至少得到它何时消失的通知。

什么使耦合“松散”并且编写松散耦合的代码更好?

可能重复: 什么是“松散耦合?”请提供示例。 什么使耦合“松散”并且编写松散耦合的代码更好? **请提供一些链接。

如何在数据访问层中管理SqlDataReaders?

我试图更好地解决我的代码,代码重用等问题。 每次我想阅读一些行时,我都厌倦了输入以下内容: using(SqlConnection conn = new SqlConnection(myConnString)) { using(SqlCommand cmd = new SqlCommand(cmdTxt, conn)) { conn.Open(); using(SqlDataReader rdr = cmd.ExecuteReader()) { while(rdr.Read()) { /* do something with rows */ } } } } 我知道有LINQ to SQL(我不喜欢它),以及entity framework(还是个孩子)。 我没有问题必须输出我的查询,我只是不想每次都要输入命令contruction,row iterator等。 我环顾四周,发现了一些我觉得适合我的东西,并试图实现它以使我更容易。 正如您在注释中看到的,我收到SqlDataReader关闭的错误。 我猜它可能是因为DataFactory.ExecuteReader()方法中的using语句。 返回阅读器时,将在我的SqlConnection和SqlCommand变量上调用dispose方法。 我在那儿吗? 如果是这样,应该如何管理连接和命令变量? 编辑:我更新了我的代码示例,以更好地反映我正在做的事情。 public class DataFactory { public DataFactory() {} public DataFactory(string […]

仅在应用程序启动时使用DI容器?

通常,我将在c#中使用dependency injection容器(unity),如下例所示: class SomeClass { private readonly ILogger _logger; public SomeClass() { _logger = DependencyContainer.Resolve(); } public void DoSomething() { var someOtherClass = DependencyContainer.Resolve(); someOtherClass().whatElseEver(); } } 昨天,我已经阅读了一些关于使用di容器进行正确dependency injection的文章。 在此之后,我知道我的例子非常糟糕。 这不是dependency injection,这就像服务定位器。 好的,怎么解决这个? 我认为使用构造函数注入可以轻松解决此问题: class SomeClass { private readonly ILogger _logger; private readonly ISomeOtherClass _someOtherClass; public SomeClass(ILogger logger, ISomeOtherClass someOtherClass) { _logger = logger; _someOtherClass […]

entity framework和MVC在业务层或数据访问层中创建DbContext

我是Entity Framework和.NET的新手,正在开发构建MVC 4应用程序。 我想我应该创建数据库上下文实例的位置有点困惑。 在我的应用程序中,我有几个层:Web,业务,数据访问,数据库(这些是每个单独的项目)。 在数据访问层中,每个表有一个类。 我看到的一个例子显示了在数据访问层内的每个方法内创建上下文(我可能误解了它)。 当将多个表更新为业务逻辑的一部分时,这似乎不太实际。 似乎在每个数据访问层方法中创建新上下文的结果是此错误:更新多个表时An entity object cannot be referenced by multiple instances of IEntityChangeTracker 。 那么在业务层方法中创建上下文然后将其传递给数据访问层方法是否可以接受? 或者有更好的方法吗? 上下文来自业务层的类似内容: public User RetrieveUserById(int id, MyDbContext ctx) { User findUser = ctx.Users.Find(id); return findUser; } 而不是在数据访问层方法中创建上下文: public User RetrieveUserById(int id) { var ctx = new MyDbContext(); User findUser = ctx.Users.Find(id); return findUser; } […]

API设计:公开XML或对象#2

我最近问了这个问题: 暴露XML或对象 – 感谢所有回复。 有一点需要澄清。 API将始终远程访问(即作为服务),最有可能通过Web服务或WCF访问。 我同意理论上一个强类型API将对象暴露为输入/输出是正确的方法。 但是,我觉得仍有一个论据要暴露XML。 我认为使用XML的原因是: 业务规则可以由Schematron的业务分析师编写。 接口是弱类型的,但只要它被调用,就可以根据数据和业务规则validation数据。 该服务的实现将更简单。 不需要创建域对象模型。 XML模式已经定义(我们有一个模式的数据字典)。 使用Web服务技术意味着基于XML的API不需要随着新车“类型”的添加而改变,例如 void AddNewCar( string newCarXml ) string[] GetCars( /* some query conditions */ ) 如果我们使用基于对象的API,那么添加新类型将需要一个新的查询方法来定义可以返回的可能的派生类型(请参阅扩展Web服务 )。 像这样更新Web服务需要重建和重新部署此服务和所有现有客户端。 基于对象的API给我们带来了什么? 强类型声明性接口。 它不提供比XML更多的抽象(XML本身就是一个抽象)。 基于对象的API的成本是多少? 它需要一整套域对象,这些对象需要业务规则和数据validation。 那么,我的问题是什么? 给我一个不可失败的,无可争议的理由,为什么我应该与对象一起去。

为什么`Assembly`和`Module`没有公开定义的构造函数?

我正在用C#构建一个.NET程序集加载器,用于“实验”/了解有关.NET内部操作的更多信息。 我通过派生类型来实现reflectionAPI: RuntimeType:类型 RuntimeFieldInfo:FieldInfo RuntimeMethodInfo:MethodInfo RuntimeParameterInfo:ParameterInfo RuntimeConstructorInfo:ConstructorInfo RuntimePropertyInfo:PropertyInfo 不幸的是我遇到了麻烦,因为以下没有可公开访问的构造函数,所以我不能从它们派生: assembly(未密封 – AssemblyBuilder内部派生自它) 模块(未密封 – ModuleBuilder内部派生自它) 我需要从RuntimeType.get_Assembly和RuntimeType.get_Module返回一些东西。 建议? 发挥创意 – 我必须这样做。 ;)对于创建RuntimeTypeHandle实例,一些不安全的指针转换可以完成工作,但这并不容易。 暂且不说:现在特别麻烦的是我正在尝试为负载类型打印IL。 对于构造的generics, Type.FullName属性通过AssemblyQualifiedName属性包含generics参数,而AssemblyQualifiedName属性又依赖于Assembly属性。