我知道C#不支持静态方法继承.我还阅读了许多讨论(包括此处),其中开发人员声称需要此功能,典型的响应是"如果您需要静态成员继承,那么您的设计就存在缺陷".
好吧,鉴于OOP不希望我甚至考虑静态继承,我必须得出结论,我对它的明显需求指出了我的设计中的错误.但是,我被困住了.我真的很感激帮助解决这个问题.这是挑战......
我想创建一个抽象基类(我们称之为Fruit),它封装了一些复杂的初始化代码.此代码不能放在构造函数中,因为其中一些代码将依赖于虚方法调用.
Fruit将由其他具体类(Apple,Orange)继承,每个类必须公开标准工厂方法CreateInstance()以创建和初始化实例.
如果静态成员继承是可行的,我会将工厂方法放在基类中,并使用对派生类的虚方法调用来获取必须从中初始化具体实例的类型.客户端代码可以简单地调用Apple.CreateInstance()来获取完全初始化的Apple实例.
但显然这是不可能的,所以有人可以解释我的设计需要如何改变以适应相同的功能.
我正在寻找一种从.NET应用程序访问插件的简单而安全的方法.虽然我认为这是一个非常普遍的要求,但我很难找到满足我所有需求的东西:
我已经调查了MEF和MAF,但我很难看到如何使它们中的任何一个符合要求.
假设我的理解是正确的,MAF无法支持在其隔离边界上传递泛型类型,这对我的应用程序至关重要.(MAF实现起来也非常复杂,但如果我能解决泛型问题,我会准备好使用它).
MEF几乎是一个完美的解决方案,但似乎无法满足安全性要求,因为它将扩展程序集加载到与主机相同的AppDomain中,因此显然可以防止沙箱化.
我已经看到了这个问题,它讨论了在沙盒模式下运行MEF,但没有描述如何.这篇文章指出"当使用MEF时,你必须信任扩展不运行恶意代码,或通过代码访问安全提供保护",但同样,它没有描述如何.最后,有这篇文章描述了如何防止未知插件被加载,但这不适合我的情况,因为即使是合法的插件也是未知的.
我已经成功地将.NET 4.0安全属性应用于我的程序集,并且MEF正确地尊重它们,但是我没有看到这有助于我锁定恶意代码,因为许多可能是安全威胁的框架方法(例如,方法System.IO.File)标记为SecuritySafeCritical,这意味着它们可以从SecurityTransparent程序集访问.我在这里错过了什么吗?是否有一些额外的步骤我可以告诉MEF它应该为插件程序集提供互联网权限?
最后,我也看了创造我自己的简单的沙盒插件架构,使用单独的AppDomain,描述在这里.但是,据我所知,这种技术只允许我使用后期绑定来调用不受信任的程序集中的类上的静态方法.当我尝试扩展这种方法来创建我的一个插件类的实例时,返回的实例无法转换为公共插件接口,这意味着主机应用程序无法调用它.是否有一些技术可用于跨AppDomain边界获得强类型代理访问?
我为这个问题的长度道歉; 原因是要显示我已经调查过的所有途径,希望有人可以提出新的尝试.
蒂姆,非常感谢你的想法
我试图使用实体框架数据迁移,如描述的这个帖子.
但是,当我尝试执行该Enable-Migrations步骤时,我在程序包管理器控制台中收到以下错误:
The target context 'MyDataContext' is not constructible. Add a default constructor or provide an implementation of IDbContextFactory
Run Code Online (Sandbox Code Playgroud)
因此,我创建了一个IDbContextFactory在包含我的DbContext类的项目中实现的工厂类,但数据迁移似乎无法识别它.
我是否应该明确指示数据迁移使用此工厂类?
我是WPF的新手,试图建立一个项目,该项目遵循Josh Smith描述模型 - 视图 - 视图模型设计模式的优秀文章的建议.
使用Josh的示例代码作为基础,我创建了一个包含许多"工作区"的简单应用程序,每个工作区由TabControl中的选项卡表示.在我的应用程序中,工作空间是一个文档编辑器,它允许通过TreeView控件操作分层文档.
虽然我已成功打开多个工作区并在绑定的TreeView控件中查看其文档内容,但我发现TreeView在选项卡之间切换时"忘记"其状态.例如,如果Tab1中的TreeView部分展开,则在切换到Tab2并返回到Tab1后,它将显示为完全折叠.此行为似乎适用于所有控件的控件状态的所有方面.
经过一些实验,我意识到我可以通过将每个控件状态属性显式绑定到底层ViewModel上的专用属性来保留TabItem中的状态.然而,这似乎是很多额外的工作,当我只是希望我的所有控件在工作区之间切换时记住它们的状态.
我想我错过了一些简单的东西,但我不知道在哪里寻找答案.任何指导都将非常感谢.
蒂姆,谢谢
更新:
根据要求,我将尝试发布一些演示此问题的代码.但是,由于作为TreeView基础的数据很复杂,我将发布一个展示相同symtoms的简化示例.这是主窗口中的XAML:
<TabControl IsSynchronizedWithCurrentItem="True" ItemsSource="{Binding Path=Docs}">
<TabControl.ItemTemplate>
<DataTemplate>
<ContentPresenter Content="{Binding Path=Name}" />
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
<DataTemplate>
<view:DocumentView />
</DataTemplate>
</TabControl.ContentTemplate>
</TabControl>
Run Code Online (Sandbox Code Playgroud)
上面的XAML正确绑定到DocumentViewModel的ObservableCollection,其中每个成员都通过DocumentView呈现.
为了简化这个例子,我从DocumentView中删除了TreeView(如上所述),并将其替换为包含3个固定标签的TabControl:
<TabControl>
<TabItem Header="A" />
<TabItem Header="B" />
<TabItem Header="C" />
</TabControl>
Run Code Online (Sandbox Code Playgroud)
在这种情况下,DocumentView和DocumentViewModel之间没有绑定.运行代码时,内部TabControl在切换外部TabControl时无法记住其选择.
但是,如果我显式绑定内部TabControl的SelectedIndex属性...
<TabControl SelectedIndex="{Binding Path=SelectedDocumentIndex}">
<TabItem Header="A" />
<TabItem Header="B" />
<TabItem Header="C" />
</TabControl>
Run Code Online (Sandbox Code Playgroud)
...到DocumentViewModel上的相应虚拟属性...
public int SelecteDocumentIndex { get; set; }
Run Code Online (Sandbox Code Playgroud)
...内部标签能够记住它的选择.
我知道我可以通过将这种技术应用到每个控件的每个视觉属性来有效地解决我的问题,但我希望有一个更优雅的解决方案.
我的应用程序初始化$ rootScope中的对象图,就像这样......
var myApp = angular.module('myApp', []);
myApp.run(function ($rootScope) {
$rootScope.myObject = { value: 1 };
});
Run Code Online (Sandbox Code Playgroud)
...然后从该对象图中消耗数据(仅限单向绑定),就像这样......
<p>The value is: {{myObject.value}}</p>
Run Code Online (Sandbox Code Playgroud)
这工作正常,但如果我随后(在页面渲染完成后)尝试更新$ rootScope并用新的替换原始对象,则会被忽略.我最初认为这是因为AngularJS保留了对原始对象的引用,即使我已经替换它.
但是,如果我将消耗的HTML包装在控制器中,我能够以预期的方式重复更新其范围,并且修改将正确地反映在页面中.
myApp.controller('MyController', function ($scope, $timeout) {
$scope.myObject = { value: 3 };
$timeout(function() {
$scope.myObject = { value: 4 };
$timeout(function () {
$scope.myObject = { value: 5 };
}, 1000);
}, 1000);
});
Run Code Online (Sandbox Code Playgroud)
有没有办法通过$ rootScope实现这一点,还是只能在控制器内完成?此外,是否有更推荐的模式来实施此类操作?具体来说,我需要一种方法来替换AngularJS从AngularJS代码之外使用的完整对象图.
蒂姆,提前谢谢你的建议
编辑:正如评论中所建议的,我已经尝试在$ apply中执行更改,但它没有帮助:
setTimeout(function() {
var injector = angular.injector(["ng", "myApp"]);
var rootScope = injector.get("$rootScope");
rootScope.$apply(function () {
rootScope.myObject = { …Run Code Online (Sandbox Code Playgroud) 我目前正在为MVC4应用程序中的存储库实现编写单元测试.为了模拟数据上下文,我开始采用这篇文章中的一些想法,但我现在发现了一些限制,让我怀疑是否有可能正确模拟IQueryable.
特别是,我已经看到了一些测试通过但代码在生产中失败的情况,并且我无法找到任何方法来模拟导致此失败的行为.
例如,以下代码段用于选择Post属于预定义类别列表的实体:
var posts = repository.GetEntities<Post>(); // Returns IQueryable<Post>
var categories = GetCategoriesInGroup("Post"); // Returns a fixed list of type Category
var filtered = posts.Where(p => categories.Any(c => c.Name == p.Category)).ToList();
Run Code Online (Sandbox Code Playgroud)
在我的测试环境中,我试图嘲弄posts使用假DbSet上面提到的实施,同时也通过创建List的Post实例并将其转换为IQueryable使用AsQueryable()扩展方法.这两种方法都在测试条件下工作,但代码实际上在生产中失败,但有以下例外:
System.NotSupportedException : Unable to create a constant value of type 'Category'. Only primitive types or enumeration types are supported in this context.
虽然像这样的LINQ问题很容易解决,但真正的挑战是找到它们,因为它们不会在测试环境中显示出来.
我期望我可以嘲笑实体框架的实施行为,这是不现实的IQueryable吗?
谢谢你的想法,
蒂姆.
任何人都可以建议一个XPath表达式格式,它返回一个字符串值,包含元素的某些符合条件的子节点的连接值,但忽略其他子节点:
<div>
This text node should be returned.
<em>And the value of this element.</em>
And this.
<p>But this paragraph element should be ignored.</p>
</div>
Run Code Online (Sandbox Code Playgroud)
返回的值应该是单个字符串:
This text node should be returned. And the value of this element. And this.
Run Code Online (Sandbox Code Playgroud)
这可能在单个XPath表达式中吗?
谢谢.
这是我第一次使用AngularUI路由器,所以我想我正在制作一个新手错误,并希望有人可以指导我.
我已经配置了一个单页面应用程序,以便在HTML5模式下使用Angular UI路由器,它似乎都按预期工作.
.config([
"$stateProvider", "$urlRouterProvider", "$locationProvider",
function ($stateProvider, $urlRouterProvider, $locationProvider) {
$stateProvider.state("concept", {
url: "/concepts/:conceptKey",
templateUrl: "/templates/concept-view.html",
controller: "conceptViewController",
resolve: {
concept: [
"$stateParams", "conceptsApi",
function ($stateParams, conceptsApi) {
return conceptsApi.getConcept($stateParams.conceptKey);
}
]
}
});
$urlRouterProvider.otherwise("/");
$locationProvider.html5Mode(true);
}
])
Run Code Online (Sandbox Code Playgroud)
但是,同一页面还包含一些指向同一站点上其他静态页面的链接,使用相对URL.在安装Angular路由之前,这些链接可以正常工作,但现在它们已经坏了.具体来说,单击这些链接中的任何一个都会正确更改浏览器地址栏,但不会触发导航到该目标页面.
我假设我需要添加一些东西来告诉路由配置忽略某些URL模式,但我没有找到任何信息告诉我如何执行此操作.有什么建议吗?
蒂姆,谢谢
我对WPF和NHibernate都比较陌生,并尝试使用MVVM模式构建一个将两者结合起来的应用程序.但是,我很难理解我的应用程序何时何地应该打开和关闭NHibernate会话和事务.
根据我的阅读,建议会话应尽可能短.因此,除了明显的线程安全考虑之外,我认为在应用程序级别打开会话并分享它是不正确的?另一方面,我也意识到非常短的会话(在业务方法中作用域)将导致分离的实体,并且还阻止我利用NHibernate的延迟加载.这是设计WPF/NH应用程序的正常且不可避免的方式吗?
不幸的是,所有好的代码示例(以及我在这个主题上可以找到的唯一一本书 - NHibernate in Action)都专注于ASP.NET应用程序,其中最佳实践显然是相当明确的 - 会话和事务完全跨越一个Http请求.
所以,我希望WPF开发人员提供一些指导,帮助我理解WPF中的会话管理(理想情况下指向一些好的代码示例).
非常感谢,
蒂姆
我有一个ASP.NET MVC4应用程序(我认为)自从一年前首次发布以来一直在使用JavaScript和CSS捆绑.在此期间,我们发布了大量更新,并且没有看到脚本传送出现问题的证据.
但是,通过我们最新的代码部署,我注意到服务的JavaScript不是最新的,并且无论底层脚本内容发生什么变化,脚本包请求中使用的查询字符串参数都不会更改.
我尝试在Visual Studio中重建解决方案,并验证修改后的脚本文件是否正确部署到服务器.我还明确地回收了IIS应用程序池并重新启动了服务器,但问题仍然存在.
有任何想法如何诊断或解决这个问题?
更新:刚刚比较了暂存和生产服务器,我注意到了行为上的差异.使用Visual Studio Web部署以相同方式部署两个服务器.登台服务器通过更新它在引用脚本包的URL中使用的哈希值,正确并立即反映脚本文件的更改.相反,生产服务器无法更新其捆绑哈希以响应脚本文件修改和/或更改脚本包的组成(即使在重新启动IIS或回收应用程序池之后).这表明该问题与生产IIS环境隔离,并且与我的代码更改或Visual Studio配置无关.
.net ×2
mvvm ×2
wpf ×2
angularjs ×1
asp.net-mvc ×1
binding ×1
c# ×1
inheritance ×1
iqueryable ×1
maf ×1
mef ×1
mocking ×1
nhibernate ×1
rootscope ×1
sandbox ×1
session ×1
state ×1
static ×1
tabcontrol ×1
transactions ×1
xpath ×1