我编写了一个由多个类实现的接口.我想写一个Service类,它将所有注册的实现注入到它的ctor中.
我能想到的唯一解决方案是在ctor中调用服务定位器并要求它Resolve()所有实现.
理想情况下,我想要这样的东西 -
interface IVehicle
{
void Start();
}
class Car : IVehicle
{
public void Start()
{
Console.WriteLine("Car started.");
}
}
class Truck : IVehicle
{
public void Start()
{
Console.WriteLine("Truck started.");
}
}
class Motorbike : IVehicle
{
public void Start()
{
Console.WriteLine("Motorbike started.");
}
}
class VehicleService
{
// How do I inject all implementations of IVehicle?
public VehicleService(IEnumerable<IVehicle> vehicles)
{
foreach (var vehicle in vehicles)
{
vehicle.Start();
}
}
}
Run Code Online (Sandbox Code Playgroud)
编辑 - 我应该提到我正在使用Castle Windsor.
我想定义一条路线如下 -
[Route("clients/{*code}/{id:guid}/update")]
public ActionResult Update(string code, Guid id)
{
}
Run Code Online (Sandbox Code Playgroud)
代码将类似于"foo/bar/xyz".
不幸的是,开箱即用的MVC不支持路径定义中间的贪婪参数.
Serilog允许创建一个上下文感知记录器:
Log.ForContext<T>()
我想用SimpleInjector注册Serilog,这T是消费者的类型,即它注入的是哪个类.
例如
public class Car
{
public Car(ILogger logger) <= would be injected using Log.ForContext<Car>()
{
}
}
Run Code Online (Sandbox Code Playgroud)
我可以看到这已经完成了AutoFac.
通过SimpleInjector文档,有一个非常有希望的重载RegisterConditional()(使用Func<TypeFactoryContext, Type>参数).
c.RegisterConditional(typeof (ILogger),
x => Log.ForContext(x.Consumer.ImplementationType), <= won't compile as expecting a Type
Lifestyle.Scoped,
x => true);
Run Code Online (Sandbox Code Playgroud)
但是,我不想告诉SimpleInjector 要构建哪个 Type,而是如何构建一个.
我可以想象这在Castle中可能会非常直接,但我对这项技术不熟悉并且谷歌搜索了好几个小时没有运气!
我有以下内容:
container.Register(
Component.For<MySpecialClass>().UsingFactoryMethod(
() => new MySpecialClass()).LifeStyle.Singleton);
Run Code Online (Sandbox Code Playgroud)
现在非常正确,这是延迟加载的,即传递给UsingFactoryMethod()的lambda表达式在我实际要求Castle解析类的实例之前没有被执行.
但是我希望Castle在我注册后立即创建实例.这可能吗?
如何在Visual Studio中的QuickWatch窗口中查看Stream的内容?
更新
根据Daniel的回答,我使用了以下代码 -
System.Text.Encoding.UTF8.GetString((byte[])stream.GetType().GetMethod("InternalGetBuffer", System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.NonPublic).Invoke(stream, null))
我在我的测试MVC3项目中映射了以下路由 -
routes.MapRoute(
"TestRoute",
"test/{DateFrom}/{DateTo}",
new { controller = "Home", action = "TestRoute" }
);
Run Code Online (Sandbox Code Playgroud)
然后我在视图中建立一个链接如下 -
@Html.ActionLink("Test Link", "TestRoute", new
{
DateFrom = new DateTime(2006, 02, 16),
DateTo = new DateTime(2008, 04, 22)
})
Run Code Online (Sandbox Code Playgroud)
在渲染时,输出此URL -
/test/02/16/2006%2000%3a00%3a00/04/22/2008%2000%3a00%3a00
Run Code Online (Sandbox Code Playgroud)
如您所见,框架调用ToString()了DateTime参数,然后对结果进行了编码.
我想格式化DateTime路由参数,以便它们输出为"yyyy-MM-dd".
显然我可以在构建Action Link时指定格式,如下所示 -
@Html.ActionLink("Test Link", "TestRoute", new
{
DateFrom = new DateTime(2006, 02, 16).ToString("yyyy-MM-dd"),
DateTo = new DateTime(2008, 04, 22).ToString("yyyy-MM-dd")
})
Run Code Online (Sandbox Code Playgroud)
但是我们知道这很麻烦,很麻烦而且不干.
我已经尝试[DisplayFormat(DataFormatString = "{0:dd-MM-yyyy}")]在模型中的属性上使用属性,希望这是答案,但是看起来这些只在构建编辑器表单时才受到尊重.
仅供参考,如果我DateTime在浏览器中手动输入URL中的参数(例如/ test/2006-02-16/2008-04-22),参数会被正确解析,因此只需要按照我想要的格式对它们进行格式化.
我收到以下异常:
NSubstitute.Exceptions.NotASubstituteException:NSubstitute扩展方法(如.Received())只能在使用Substitute.For()和相关方法创建的对象上调用。
...在调用chargeService.When()时:
public class WhenUserTopsUpAndStripeRejectsPaymentRequest
{
[Theory, AutoNSubstituteData]
public void it_should_throw_AutoTopUpFailedException(
[Frozen] StripeChargeService chargeService,
[Frozen] IRepository repository,
TopUpUserAccountBalance message,
TopUpUserAccountBalanceHandler sut) <== has dependency on StripeChargeService
{
repository.Find(Arg.Any<ById<User>>())
.Returns(new User
{
AutoTopUpEnabled = true,
AccountBalance = -15
});
=====> chargeService.When(s => s.Create(Arg.Any<StripeChargeCreateOptions>()))
.DoNotCallBase();
Assert.Throws<AutoTopUpFailedException>(() => sut.Handle(message));
}
}
Run Code Online (Sandbox Code Playgroud)
现在,我当然可以按照异常建议进行操作,并手动创建StripeChargeService,然后手动创建所有依赖项并将其注入到SUT中,以解决此问题,但是我宁愿使用更少的代码并让AutoFixture完成工作。
public class AndStripeRejectsPaymentRequest
{
[Theory, AutoNSubstituteData]
public void it_should_throw_AutoTopUpFailedException(
IMediator mediator,
IBillingConfig config,
[Frozen] IRepository repository,
TopUpDriverAccountBalance message)
{
var chargeService = Substitute.ForPartsOf<StripeChargeService>("");
repository.Find(Arg.Any<ById<Driver, TopUpDriverAccountBalanceHandler.DriverProjection>>())
.Returns(new TopUpDriverAccountBalanceHandler.DriverProjection
{
AutoTopUpEnabled = …Run Code Online (Sandbox Code Playgroud) 假设我想通过按位移位来增加数字,即
1, 2, 4, 8, 16, etc
有没有办法将i = i << 1下面的内容压缩为增量运算符(++)之类的东西?
for (int i = 1; i <= 256; i = i << 1)
{
Console.WriteLine(i);
}
Run Code Online (Sandbox Code Playgroud) 当你调用a时,Action<T>你将传入一个T类型的变量,该变量可用于委托中定义的代码,例如
var myAction = new Action<string>(param =>
{
Console.WriteLine("This is my param: '{0}'.", param);
});
myAction("Foo");
// Outputs: This is my param: 'Foo'.
Run Code Online (Sandbox Code Playgroud)
当你调用Func<T>委托时,会返回一个T类型的变量,例如
var myFunc = new Func<string>(() =>
{
return "Bar";
});
Console.WriteLine("This was returned from myFunc: '{0}'.", myFunc());
// Outputs: This was returned from myFunc: 'Bar'.
Run Code Online (Sandbox Code Playgroud)
这是问题 -
有这将需要输入参数和第三委托类型也返回一个值?就像是 -
var fooDeletegate = new FooDelegate<string, int>(theInputInt =>
{
return "The Answer to the Ultimate Question of Life, the Universe, and Everything …Run Code Online (Sandbox Code Playgroud)