我正在为我的IoC类库重写我的流畅界面,当我重构一些代码以便通过基类共享一些常用功能时,我遇到了麻烦.
注意:这是我想要做的事情,而不是我必须做的事情.如果我必须使用不同的语法,我会,但如果有人知道如何使我的代码按我想要的方式编译,那将是非常受欢迎的.
我希望某些扩展方法可用于特定的基类,并且这些方法应该是通用的,具有一个泛型类型,与方法的参数相关,但是这些方法也应该返回与特定后代相关的特定类型.被引用.
使用代码示例比上面的描述更好.
这是一个简单而完整的例子,它不起作用:
using System;
namespace ConsoleApplication16
{
public class ParameterizedRegistrationBase { }
public class ConcreteTypeRegistration : ParameterizedRegistrationBase
{
public void SomethingConcrete() { }
}
public class DelegateRegistration : ParameterizedRegistrationBase
{
public void SomethingDelegated() { }
}
public static class Extensions
{
public static ParameterizedRegistrationBase Parameter<T>(
this ParameterizedRegistrationBase p, string name, T value)
{
return p;
}
}
class Program
{
static void Main(string[] args)
{
ConcreteTypeRegistration ct = new ConcreteTypeRegistration(); …Run Code Online (Sandbox Code Playgroud) 我如何设计一个API来隐藏AJAX和HTTP请求的异步性质,或者基本上将其延迟以提供流畅的界面.要在Twitter的新Anywhere API中显示示例:
// get @ded's first 20 statuses, filter only the tweets that
// mention photography, and render each into an HTML element
T.User.find('ded').timeline().first(20).filter(filterer).each(function(status) {
$('div#tweets').append('<p>' + status.text + '</p>');
});
function filterer(status) {
return status.text.match(/photography/);
}
Run Code Online (Sandbox Code Playgroud)
vs this(每个调用的异步性质清晰可见)
T.User.find('ded', function(user) {
user.timeline(function(statuses) {
statuses.first(20).filter(filterer).each(function(status) {
$('div#tweets').append('<p>' + status.text + '</p>');
});
});
});
function filterer(status) {
return status.text.match(/photography/);
}
Run Code Online (Sandbox Code Playgroud)
它找到用户,获取他们的推文时间轴,仅过滤前20条推文,应用自定义过滤器,并最终使用回调函数来处理每条推文.
我猜这样设计良好的API应该像查询构建器(想想ORM)一样工作,每个函数调用构建查询(在这种情况下为HTTP URL),直到它遇到循环函数,如每个/ map /等.进行HTTP调用,传入函数成为回调函数.
一个简单的开发途径是使每个AJAX调用同步,但这可能不是最好的解决方案.我有兴趣找出使其异步的方法,并仍然隐藏AJAX的异步性质.
背景:
我们有一个包含许多模块的项目.我们将EntityFramework 4.2与FluentAPI(CodeFirst)一起使用.
有一个名为Diverto.ORM.EntityFramework.SQLServer的中心项目,它包含使用FluentAPI构建上下文的部分类(并且它引用了解决方案中的所有其他项目).
最近我们收到了客户要求实施许多其他功能的请求,该解决方案还需要其他几个项目.其中一些项目将来自另一个系统(人力资源),一些将被创建.现有解决方案的核心是财务系统.
我们希望使用MEF"动态"启用和禁用这些新项目(以及GUI,业务逻辑和所有项目).它们将作为插件进行交互,应用程序的主菜单也将使用MEF进行填充.
但是,由于它们必须共享的数据,我们并不真正了解如何启用/禁用这些模块/项目(新模块/项目).
考虑一下:
- 使用DbSet <ClassA>和DbSet <ClassB>的DivertoContext(主上下文).
- 使用DbSet <ClassC>的PluginContext(来自插件).
现在,考虑到在GUI内部,我必须能够访问ClassA,ClassB和ClassC中的数据(如果插件存在的话).
找到解决方案 见下文
我注意到有人在检查这个并将其标记为最喜欢或最喜欢的.请记住,这个答案可以追溯到2012年,EntityFramework 自那以后发生了很大的变化.
另外,拜托,请,请记住,每个项目都有自己的需求.那时候,我需要这个功能.您的项目可能根本不需要这个,或者只是其中的一部分!
最后,只是为了确保一切都被掩盖,是的,可以使用EF 6.1和EF迁移来实现这一点,也可以使用其他ORM和迁移框架.
您可能需要一些其他接口,作为迁移加载的接口,并正确处理特定的插件迁移(不要将其与其他插件混合使用,因此请尝试为每个插件实现某种独特的令牌).
我最近接触过nUnit中的流畅界面,我喜欢它; 但是,我正在使用msTest.
有没有人知道是否有一个流畅的界面,无论是测试框架不可知还是msTest?
如何创建一个流畅的界面而不是更传统的方法?这是一种传统的方法:
接口:
interface IXmlDocumentFactory<T>
{
XmlDocument CreateXml() //serializes just the data
XmlDocument CreateXml(XmlSchema schema) //serializes data and includes schema
}
interface IXmlSchemaFactory<T>
{
XmlSchema CreateXmlSchema() //generates schema dynamically from type
}
Run Code Online (Sandbox Code Playgroud)
用法:
var xmlDocFactory = new XmlDocumentFactory<Foo>(foo);
var xmlDocument = xmlDocFactory.CreateXml();
//or...
var xmlDocFactory = new XmlDocumentFactory<Foo>(foo);
var xmlSchemaFactory = new XmlSchemaFactory<Foo>();
var xmlDocument = xmlDocFactory.CreateXml(xmlSchemaFactory.CreateXmlSchema());
Run Code Online (Sandbox Code Playgroud)
我想能够说:
var xmlDocument = new XmlDocumentFactory<Foo>(foo).CreateXml().IncludeSchema();
//or...
var xmlDocument = new XmlDocumentFacotry<Foo>(foo).CreateXml();
Run Code Online (Sandbox Code Playgroud)
最后,这种情况是否适合流畅的界面?或者更传统的方法会更有意义吗?
假设我有一个具有一些属性的类和一些用于操作这些属性的方法:
public class PersonModel
{
public string Name { get; set; }
public string PrimaryPhoneNumber { get; set; }
public void LoadAccountInfo(AccountInfo accountInfo)
{
this.Name = accountInfo.Name;
}
public void LoadPhoneInfo(PhoneInfo phoneInfo)
{
this.PrimaryPhoneNumber = phoneInfo.PhoneNumber;
}
}
Run Code Online (Sandbox Code Playgroud)
典型用法是:
var model = new PersonModel();
model.LoadAccountInfo(accountInfo);
model.LoadPhoneInfo(phoneInfo);
Run Code Online (Sandbox Code Playgroud)
我认为将方法链接起来会很酷:
public PersonModel LoadAccountInfo(AccountInfo accountInfo)
{
this.Name = accountInfo.Name;
return this;
}
public PersonModel LoadPhoneInfo(PhoneInfo phoneInfo)
{
this.PrimaryPhoneNumber = phoneInfo.PhoneNumber;
return this;
}
Run Code Online (Sandbox Code Playgroud)
那么用法是:
var model = new PersonModel()
.LoadAccountInfo(accountInfo)
.LoadPhoneInfo(phoneInfo);
Run Code Online (Sandbox Code Playgroud)
但是我没有在每个可链接的方法中返回传入的PersonModel对象的修改"克隆".他们只是修改原始对象并返回它(为方便起见).对我来说,这会产生歧义,因为有人调用这些方法可能会认为它们是不可变的(即它们保持原始对象完整但返回修改后的对象).
这是否违反了关于流畅/可链接接口的任何最佳实践?
我有一个带有自引用的表,其中ParentId是ID(PK)的FK.
使用EF(代码优先),我建立了如下关系:
this.HasOptional(t => t.ParentValue)
.WithMany(t => t.ChildValues)
.HasForeignKey(t => t.ParentId);
Run Code Online (Sandbox Code Playgroud)
当我尝试删除子节点及其父节点时,DELETE命令对数据库的EF问题不按我预期的顺序 - 它首先尝试删除父节点.
我意识到我在这里有几个选项(我都不喜欢):
所以问题是..有没有办法在父记录之前强制删除子项?也许我错过了某种明确的方式告诉EF它需要在父母之前照顾这些孩子?也许有一种方法可以指示EF按ID的降序删除?我不知道......想法?
我有一个班级,我必须多次互相称呼一两种方法.目前返回的方法void.我在想,让它返回会更好this,这样方法可以嵌套吗?或者这是非常非常非常糟糕的?或者,如果它返回一个相同类型的新对象会更好吗?或者您怎么看?作为一个例子,我创建了三个版本的加法器类:
// Regular
class Adder
{
public Adder() { Number = 0; }
public int Number { get; private set; }
public void Add(int i) { Number += i; }
public void Remove(int i) { Number -= i; }
}
// Returning this
class Adder
{
public Adder() { Number = 0; }
public int Number { get; private set; }
public Adder Add(int i) { Number += i; return this; }
public Adder Remove(int i) …Run Code Online (Sandbox Code Playgroud) 我最近遇到了这个表达 - 但是在维基百科上阅读并没有对我说明多少 - 我仍然没有得到它:
[编辑] 维基百科文章C++示例过长,并将流畅的界面讨论与简单的Glut应用程序的示例混为一谈.有人可以提供一个类的SUCCINCT C++示例来说明一个流畅的界面(例如,这种影响与普通的C++界面有何不同)?
我有一个API,我正在变成一个内部DSL.因此,我的PoJos中的大多数方法返回对此的引用,以便我可以声明性地将方法链接在一起(语法糖).
myComponent
.setID("MyId")
.setProperty("One")
.setProperty2("Two")
.setAssociation(anotherComponent)
.execute();
Run Code Online (Sandbox Code Playgroud)
我的API不依赖于Spring,但我希望通过PoJo友好,零参数构造函数,getter和setter使其成为"Spring-Friendly".问题是,当我有一个非void返回类型时,Spring似乎没有检测到我的setter方法.
在将命令链接在一起时,返回类型非常方便,所以我不想破坏我的编程API,只是为了兼容Spring注入.
Spring中有一个设置允许我使用非void setter吗?
克里斯
fluent-interface ×10
c# ×5
.net ×3
fluent ×2
ajax ×1
asynchronous ×1
c++ ×1
coding-style ×1
generics ×1
java ×1
javascript ×1
mef ×1
methods ×1
mstest ×1
reflection ×1
return-value ×1
spring ×1
sql-server ×1
unit-testing ×1