好的,现在我真的很困惑.
我最初遇到这个问题,根据海报,问题是Castle.DynamicProxy的版本是ILMerged到最新的Rhino.Mocks库.据该主题的一些权威人士称,它已经在最新的城堡中得到了修复,但该库还没有成为新的Rhino.Mocks.大多数人都说"只需下载Rhino源代码和最新的Castle并构建自己的版本".
所以,我做到了这一点; 我从Ayende的GitHub抓起一个Rhino主干来源的ZIP,打开它并建造它.然后,就像一个好的小TDDer,我创建了一个单元测试,以确保我的更改工作(因为最新的Castle将DynamicProxy折叠到Core中,需要一些重要的引用更改):
[Test]
public void MockOfInterfaceMethodWithInterfaceGTR()
{
var mock = mocks.DynamicMock<ITestRestrictedInterface>();
Assert.NotNull(mock);
Expect.Call(mock.TestMethod(new Object2())).IgnoreArguments().Return(5);
mocks.ReplayAll();
Assert.AreEqual(5, mock.TestMethod(new Object2()));
}
...
internal interface ITestGenericInterface<TRest> where TRest:IObject1
{
int TestMethod<T>(T input) where T : TRest;
}
internal interface ITestRestrictedInterface:ITestGenericInterface<IObject2> { }
internal interface IObject1 { }
internal interface IObject2:IObject1 { }
internal class Object2:IObject2 { }
Run Code Online (Sandbox Code Playgroud)
结果,在我自己的生产代码中使用最新发布的Rhino运行?失败并显示以下消息:
System.TypeLoadException:来自程序集'DynamicProxyGenAssembly2,Version = 0.0.0.0,Culture = neutral,PublicKeyToken = null'的类型'ITestRestrictedInterfaceProxy83ad369cdf41472c857f61561d434436'上的方法'TestMethod'试图隐式地实现具有较弱类型参数约束的接口方法.
...但是,当我将此测试复制并粘贴到Rhino.Mocks.Tests项目中的fixture中时,不对引用的库进行任何更改,测试PASSES.我对下载的源进行了零更改.我对两侧的测试方法和相关接口/对象进行了ZERO更改.我构建了一个新的Rhino.Mocks DLL(没有IL合并Castle libs)并将它与Castle libs一起复制回我的生产解决方案,重新运行测试,它仍然失败并显示相同的消息.
WTF?
任何人都可以指向一个基本的Windows窗体TextBox的良好实现,它最初会显示水印文本,当光标进入时它会消失吗?我想我可以通过创造性地使用Enter和Leave事件来创建我自己的东西,但我确信在某个地方有一个完全可用的实现.我看到了WPF实现,如果有必要,我可以嵌套它,但原生的WinForms TextBox派生会更好.
到目前为止,我有这个; 尚未尝试过,但有没有人看到任何明显的问题?
public class WatermarkTextBox:TextBox
{
public string WatermarkText { get; set; }
public Color WatermarkColor { get; set; }
private Color TextColor { get; set; }
private bool isInTransition;
public WatermarkTextBox()
{
WatermarkColor = SystemColors.GrayText;
}
private bool HasText { get { return Text.IsNotNullOrBlankOr(WatermarkText); }}
protected override void OnEnter(EventArgs e)
{
base.OnEnter(e);
if (HasText) return;
isInTransition = true;
ForeColor = TextColor;
Text = String.Empty;
isInTransition = false;
}
protected override void OnForeColorChanged(EventArgs e)
{
base.OnForeColorChanged(e);
if (!isInTransition) …
Run Code Online (Sandbox Code Playgroud) 非常简单:除了ConcurrentDictionary(我将使用它,但它不是真正正确的概念),是否有任何Concurrent集合(IProducerConsumer实现)支持基于项或谓词的简单相等删除特定项定义删除条件?
说明:我有一个多线程,多阶段的工作流算法,它从数据库中提取对象并将它们放在"起始"队列中.从那里他们被下一阶段抓住,进一步努力,并塞进其他队列.这个过程将持续几个阶段.同时,第一个阶段由其主管再次调用,并将对象拉出数据库,这些对象可以包括仍处于进行中的对象(因为它们尚未完成处理,因此没有使用标记集重新保留他们已经完成了).
我正在设计的解决方案是一个主要的"工作"集合; 当第一阶段检索到对象进行处理时,对象进入该队列,并且在完成必要处理的工作流程的任何阶段"处理"后,对象被重新保存到数据库后被删除.当对象在该列表中时,如果第一阶段重新检索它,它将被忽略.
我曾计划使用ConcurrentBag,但唯一的删除方法(TryTake)从包中删除任意项,而不是指定的项(并且.NET 4中的ConcurrentBag很慢).ConcurrentQueue和ConcurrentStack也不允许删除除了它将给你的下一个项目之外的项目,留下ConcurrentDictionary,它可以工作但是比我需要的更多(我真正需要的是存储正在处理的记录的Id;它们在工作流程中不会改变).
所以这个类似乎很少使用:SecureString.它至少从2.0开始就存在,并且有一些SO问题,但我想我会问自己的具体问题:
我有一个LoginForm; 带有用户名和(掩码)密码字段的简单WinForms对话框.当用户同时输入并单击"登录"时,信息将传递到执行一层键扩展的注入认证类,然后散列一半拉伸键进行验证,而另一半是加密用户的对称密钥帐户数据.完成所有这些操作后,将关闭loginForm,处理身份验证器类,然后系统继续加载主窗体.非常标准的东西,可能比标准的哈希 - 密码和比较更多一些,但是在我的情况下,简单的哈希密码将通过以明文形式存储用户数据而被打败,因为该数据包括第三个的凭证 - 派对系统(我们都知道人们如何重用密码).
这是第一个问题; 我如何使用SecureString从密码文本框中检索密码,而不是通过文本框的Text属性将其公开为普通的System.String?我假设有一种方法可以访问由CLR类包装的Textbox的非托管GDI窗口,并使用Marshal类提取文本数据.我只是不知道怎么样,而且我似乎无法找到好的信息.
这是第二个问题; 一旦我将密码作为SecureString,我如何从System.Security.Crypto命名空间将其传递给哈希提供程序?我的猜测是我使用Marshal.SecureStringToBSTR(),然后Marshal.Copy()从返回的IntPtr返回到一个字节数组.然后我可以调用Marshal.ZeroBSTR()来清理非托管内存,一旦我有哈希,我可以用Array.Clear()将托管数组清零.如果有一种更简洁的方法可以让我完全控制内存的任何托管副本的生命周期,请告诉我们.
第三个问题; 这一切真的是必要的,还是在托管内存环境中System.String固有的不安全性有点过分了?在操作系统考虑将应用程序交换到虚拟内存之前很久,任何用于存储密码(加密或其他方式)的内容都应该超出范围并且在前往垃圾收集器的路上(允许在交换文件后从交换文件中嗅探密码)硬关机的电脑).冷启动攻击是一种理论上的可能性,但实际上,这有多常见?更大的问题是现在解密的用户数据,它在整个应用程序生命周期中作为用户的一部分而挂起(因此将成为使用SecureStrings的主要候选者,因为除了几个基本用法之外,它们保持相当休眠状态).
我正在向一个应用程序添加一些代码,如果它还没有运行,它将启动另一个应用程序,或者如果是,请将它带到前面.这需要少量的interop/WinAPI代码,我从其他网站获得了示例,但似乎无法在Win7中工作.
如果窗口处于某种可见状态,则API的SetForegroundWindow方法就像处理一样(这将是主要情况,根据公司策略,如果外部应用程序正在运行,则不应该最小化).但是,如果它被最小化(例外但很重要,因为我的应用程序在这种情况下似乎什么也不做),这个方法和ShowWindow/ShowWindowAsync实际上都不会从任务栏中恢复窗口; 所有方法都只是突出显示任务栏按钮.
这是代码; 大部分工作都很好,但是对ShowWindow()的调用(我也尝试过ShowWindowAsync),无论我发送的命令是什么,都不会做我想要的事情:
[DllImport("user32.dll")]
private static extern int SetForegroundWindow(IntPtr hWnd);
private const int SW_SHOWNORMAL = 1;
private const int SW_SHOWMAXIMIZED = 3;
private const int SW_RESTORE = 9;
[DllImport("user32.dll")]
private static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
...
//The app is named uniquely enough that it can't be anything else,
//and is not normally launched except by this one.
//so this should normally return zero or one instance
var processes = Process.GetProcessesByName("ExternalApp.exe");
if (processes.Any()) //a copy is already …
Run Code Online (Sandbox Code Playgroud) 我注意到这个代码在我的构造函数中出现了很多:
if (someParam == null) throw new ArgumentNullException("someParam");
if (someOtherParam == null) throw new ArgumentNullException("someOtherParam");
...
Run Code Online (Sandbox Code Playgroud)
我有一些构造函数,其中注入了几个东西,并且必须都是非null.谁能想到一种简化这种方法的方法?我唯一能想到的是以下几点:
public static class ExceptionHelpers
{
public static void CheckAndThrowArgNullEx(IEnumerable<KeyValuePair<string, object>> parameters)
{
foreach(var parameter in parameters)
if(parameter.Value == null) throw new ArgumentNullException(parameter.Key);
}
}
Run Code Online (Sandbox Code Playgroud)
但是,使用它会是这样的:
ExceptionHelper.CheckAndThrowArgNullEx(new [] {
new KeyValuePair<string, object>("someParam", someParam),
new KeyValuePair<string, object>("someOtherParam", someOtherParam),
... });
Run Code Online (Sandbox Code Playgroud)
...这并没有真正帮助简化代码.Tuple.Create()而不是KVP不起作用,因为Tuple的GTP不协变(即使IEnumerable的GTP是).有任何想法吗?
首先,是的,我知道VS Setup Projects是邪恶的.这就是我必须要做的事情.我还看到了几个相关的问题,但是他们要么没有得到答复,要么他们的情况与我的情况不符,足以让他们找到工作的答案(或者他们对VS Setup Projects和WiX的奇迹有所了解).
我有一个应用程序的安装项目.它可以很好地复制文件,但我需要在复制文件后执行两个自定义操作.我创建了一个安装程序类,并将其设置为安装项目中的自定义操作,并且它的框架(没有工作,只显示一个对话框,所以我可以附加调试器并环顾四周)工作得很好.然后,我发现我需要将参数从MSI传递到我的自定义操作,以便我可以通过安装程序类的Context属性访问它们.
这是安装程序类的当前代码(某些名称已被更改以保护无辜者).它基本上什么都不做,只是在正确的时间显示一个对话框(在复制文件之后但在提交安装之前):
namespace MyApp.Install.CustomSetup
{
[RunInstaller(true)]
public partial class MyAppCustomInstallActions : System.Configuration.Install.Installer
{
public MyAppCustomInstallActions()
{
InitializeComponent();
}
protected override void OnAfterInstall(IDictionary savedState)
{
try
{
base.OnAfterInstall(savedState);
if (MessageBox.Show(
"Custom Action OnAfterInstall successfully integrated. You can attach a debugger if desired. Do you wish to perform the custom actions?",
"DEBUG", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) return;
SetEditablePermissionOnFolder(savedState);
SetApplicationSettingsFromWizard(savedState);
}
catch (Exception ex)
{
Context.LogMessage(ex.ToString());
throw;
}
}
private void SetApplicationSettingsFromWizard(IDictionary savedState)
{
//TODO: Implement
}
private …
Run Code Online (Sandbox Code Playgroud) 我的存储库在UnitOfWork
模型中工作; 所有操作,无论是检索还是持久性,都必须在IDisposable
UnitOfWork
令牌对象的范围内执行,后者在后面与Session
执行请求的工作相关联.所以,基本模式是:
using (var uow = repo.BeginUnitOfWork())
{
try
{
//DB operations here; all repo methods require passing in uow.
...
repo.CommitUnitOfWork(uow);
}
catch(Exception)
{
repo.RollbackUnitOfWork(uow);
throw;
}
}
Run Code Online (Sandbox Code Playgroud)
我还实现了一些包装器方法,允许您指定将在此框架中执行的lambda或委托,从而减少每次都需要实现所有这些脚手架的需要.
我遇到的问题是使用这个模型,代码必须"知道"用户需要什么,并NHUtil.Initialize()
在内部使用它来急切加载它UnitOfWork
.一旦UOW被放置在使用块的末尾,与any关联的Session PersistentBags
就会关闭,因此无法对它们进行评估.由于急切加载所有事情并不总是可行的,并且有点破坏了延迟加载ORM的目的,我正在实现一种Attach()
方法.
这是问题; 在没有内置ISession.Attach()
方法的情况下,我看到有三种方法建议将对象与新的Session相关联.完成工作的最佳做法是哪一项?
A:
if(!Session.Contains(domainObject))
Session.Update(domainObject);
Run Code Online (Sandbox Code Playgroud)
B:
Session.Merge(domainObject);
Run Code Online (Sandbox Code Playgroud)
C:
Session.Lock(domainObject, LockMode.None);
Run Code Online (Sandbox Code Playgroud) 我正在寻找一个能产生"字母数字哈希"的函数.给定源字符串,它会生成一个确定的结果字符串,该字符串可以包含任何字母az或数字0-9,并且不能进行反向工程以生成源.这将用于基于秘密数据为系统生成密码,因此8到12个字符之间的字符串是理想的,安全散列也是理想的.
我想我可以使用正常的按位散列,将其折叠为64位(如果我使用,例如,SHA256),然后一次取5位数(产生数字0-31)并查找要从索引的有序集合中使用的字符代码.有26个字母和10个数字意味着我将不得不留下一些(如果手写的话,可能删除可能被误认为是其他人的字符).64位,一次5位,将产生一个12字符的字符串,剩下4位.
但是,我担心两件事:首先,通过采用2的非幂次数引入偏差; 第二,如何处理剩余的比特.我是否因为知道只有16种可能性而使用它们,我是否会将它们关闭(并且丢失数据可能会引入偏差),或者我还要再加一位来制作13个字符的字符串(最后一位应该在哪里来自)?
编辑:这是我目前的努力; 它需要一个可枚举的字节(比如大多数哈希算法产生的字节数组)并返回一个字符串:
/// <summary>
/// Converts an IEnumerable of bytes to a string representation which can have any lowercase letter a-z except for l, o, q and z, and any digit 0-9.
/// Uses 5 bits of the byte array at a time to generate numbers from 0 to 31, which are then translated to letters or numbers.
/// </summary>
/// <param name="toConvert">the byte array to convert.</param>
/// <returns>A string containing the alphanumeric case-insensitive representation …
Run Code Online (Sandbox Code Playgroud) c# ×8
.net ×3
alphanumeric ×1
exception ×1
hash ×1
installer ×1
interop ×1
nhibernate ×1
rhino-mocks ×1
securestring ×1
security ×1
textbox ×1
watermark ×1
winapi ×1
windows-7 ×1
winforms ×1