Context variables in Ninject 2 - ninject

I found this article on Context Variables in an earlier version of Ninject. My question is two-fold. First, how can I get this behavior with Ninject 2? Secondly, do context variables carry through down the request chain? For example, let's say I wanted to replace these calls:
var a = new A(new B(new C())));
var specialA = new A(new B(new SpecialC()));
... with this:
var a = kernel.Get<A>();
var specialA = kernel.Get<A>(With.Parameters.ContextVariable("special", "true"));
Is it possible to set up a binding like this, where the context remembers that it is in a "special" context when it comes time to construct a C?

Here's some stuff that I use against V2, with ~0 effort to clean it up for you - let me know if you can't disentagle it.
As you surmised, there doesn't seem to be a really explicit API that surfaces the "context parameter, even for nested resolutions" stuff in v2 as-is (it's presence is buried as the 3rd parameter on an overload of the Parameter ctor).
public static class ContextParameter
{
public static Parameter Create<T>( T value )
{
return new Parameter( value.GetType().FullName, value, true );
}
}
public static class ContextParameterFacts
{
public class ProductId
{
public ProductId( string productId2 )
{
Value = productId2;
}
public string Value { get; set; }
}
public class Repository
{
public Repository( ProductId productId )
{
ProductId = productId;
}
public ProductId ProductId { get; set; }
}
public class Outer
{
public Outer( Repository repository )
{
Repository = repository;
}
public Repository Repository { get; set; }
}
public class Module : NinjectModule
{
public override void Load()
{
Bind<ProductId>().ToContextParameter();
}
}
//[ Fact ]
public static void TwoDeepShouldResolve()
{
var k = new StandardKernel( new Module() );
var o = k.Get<Outer>( ContextParameter.Create( new ProductId( "a" ) ) );
Debug.Assert( "a" == o.Repository.ProductId.Value );
}
}
And here's some code [that'll confuse the matter] which demonstrates how I apply it in my context:-
public class ServicesNinjectModule : NinjectModule
{
public override void Load()
{
Bind<ProductId>().ToContextParameter();
Bind<Func<ProductId, ResourceAllocator>>().ToConstant( ( productId ) => Kernel.Get<ResourceAllocator>(
ContextParameter.Create( productId ) ) );
}
}
public static class NinjectContextParameterExtensions
{
public static IBindingWhenInNamedWithOrOnSyntax<T> ToContextParameter<T>( this IBindingToSyntax<T> bindingToSyntax )
{
return bindingToSyntax.ToMethod( context => (T)context.Parameters.Single( parameter => parameter.Name == typeof( T ).FullName ).GetValue( context ) );
}
}
As usual, you should go look a the source and the tests - they'll provide you with a far more detailed and relevant answer than I can.

Related

How to write Xunit test case of factory design pattern code block which is tightly coupled?

I would like to write xunit test case of below method. Could you please suggest alternate design so i can write xunit test case with minimum change in my current project.
public ActionResult Index(int id = 0, AssetFilterType filter = AssetFilterType.All)
{
using (var tracer = new Tracer("AssetController", "Index"))
{
RemoveReturnUrl();
ViewBag.JobId = id;
var response = ContextFactory.Current.GetDomain<EmployeeDomain>().GetEmployeeFilterAsync(id,
CurrentUser.CompanyId, filter); // Not able write unit test case , please suggest alternate design.
return View("View", response);
}
}
current design is as follow
public interface IDomain
{
}
public interface IContext
{
D GetDomain<D>() where D : IDomain;
string ConnectionString { get; }
}
public class ApplicationContext : IContext
{
public D GetDomain<D>() where D : IDomain
{
return (D)Activator.CreateInstance(typeof(D));
}
public string ConnectionString
{
get
{
return "DatabaseConnection";
}
}
}
public class ContextFactory
{
private static IContext _context;
public static IContext Current
{
get
{
return _context;
}
}
public static void Register(IContext context)
{
_context = context;
}
}
//var response = ContextFactory.Current.GetDomain**< EmployeeDomain>**().GetEmployeeFilterAsync(id,
CompanyId, filter);
This line serve purpose to call specific class method i.e GetEmployeeFilterAsync from EmployeeDomain. Although it is very handy and widely used in our application but due to design issue i am not able to write unit
test case.
Could you please suggest design so with the minimum change we can write unit test case.
Don't use the Service Locator anti-pattern, use Constructor Injection instead. I can't tell what AssetDomain is from the OP, but it seems as though it's the dependency that matters. Inject it into the class:
public class ProbablySomeController
{
public ProbablySomeController(AssetDomain assetDomain)
{
AssetDomain = assetDomain;
}
public AssetDomain AssetDomain { get; }
public ActionResult Index(int id = 0, AssetFilterType filter = AssetFilterType.All)
{
using (var tracer = new Tracer("AssetController", "Index"))
{
RemoveReturnUrl();
ViewBag.JobId = id;
var response = AssetDomain.GetAssetFilterAsync(id, CurrentUser.CompanyId, filter);
return View("View", response);
}
}
}
Assuming that AssetDomain is a polymorphic type, you can now write a test and inject a Test Double:
[Fact]
public void MyTest()
{
var testDouble = new AssetDomainTestDouble();
var sut = new ProbablySomeController(testDouble);
var actual = sut.Index(42, AssetFilterType.All);
// Put assertions here
}
step1 : Required library
step 2 : When the application starts , register required domain like
protected void Application_Start()
UnityConfig.RegisterComponents();
Step 3: create one static class and register all your domain
example
public static class UnityConfig
{
public static void RegisterComponents()
{
var container = new UnityContainer();
Initialize domain which will injected in controller
container.RegisterType<IPricingDomain, PricingDomain>();
GlobalConfiguration.Configuration.DependencyResolver = new UnityDependencyResolver(container);
}
}
step 4 :
so you can inject respective interface in constructor
in controller file.
goal : get rid of below any pattern in your project.
and start writing unit test cases.

How can I validate different types within a collection using FluentValidation?

I have a class with a collection that needs validation. The generic on the collection takes an interface and different types can be added to the collection.
What is the cleanest path forward to creating a FluentValidation validator that supports polymorphism?
public interface IWizardStep {}
public class WizardOne : IWizardStep
{
public string Model { get; set; }
}
public class WizardTwo : IWizardStep
{
public string FirstName { get; set; }
}
public class Wizard
{
public Wizard()
{
var w1 = new WizardOne();
var w2 = new WizardTwo();
Steps = new List<IWizardStep>
{
w1,
w2
};
}
public IList<IWizardStep> Steps { get; set; }
}
public class WizardValidator : AbstractValidator<Wizard>
{
public WizardValidator()
{
RuleFor(x => x.Steps)
// Steps First where is WizardOne
// Model.NotEmpty()
// Steps First where is WizardTwo
// FirstName.NotEmpty()
}
FluentValidation doesn't support polymorphism for child collections like this out of the box, but you can add this behaviour by using a custom property validator, or by using OfType in your rule definitions.
I've written about both approaches before here:
Step 1: Create a validator for each implementor
Start by creating a validator for WizardOne and WizardTwo:
public class WizardOneValidator : AbstractValidator<WizardOne> {
public WizardOneValidator() {
RuleFor(x => x.Model).NotEmpty();
}
}
public class WizardTwoValidator : AbstractValidator<WizardTwo> {
public WizardTwoValidator() {
RuleFor(x => x.FirstName).NotEmpty();
}
}
Step 2: Create the parent validator
You have two options for defining the parent validator. The simplest approach is to use OfType, but this is less performant. The more complex option is to use a custom property validator.
Option 1: Using OfType
public WizardValidator : AbstractValidator<Wizard> {
public WizardValidator() {
RuleForEach(x => x.Steps.OfType<WizardOne>()).SetValidator(new WizardOneValidator());
RuleForEach(x => x.Steps.OfType<WizardTwo>()).SetValidator(new WizardTwoValidator());
}
}
This is the simplest approach, but calling OfType inside the call RuleFor will end up bypassing FluentValidation's expression cache, which is a potential performance hit. It also iterates the collection multiple. This may or may not be an issue for you - you'll need to decide if this has any real-world impact on your application.
Option 2: Using a custom PropertyValidator.
This uses a custom custom validator which can differentiate the underlying type at runtime:
public WizardValidator : AbstractValidator<Wizard> {
public WizardValidator() {
RuleForEach(x => x.Steps).SetValidator(new PolymorphicValidator<Wizard, IWizardStep>()
.Add<WizardOne>(new WizardOneValidator())
.Add<WizardTwo>(new WizardTwoValidator())
);
}
}
Syntactically, this isn't quite as nice, but doesn't bypass the expression cache and doesn't iterate the collection multiple times. This is the code for the PolymorphicValidator:
public class PolymorphicValidator<T, TInterface> : ChildValidatorAdaptor<T, TInterface> {
readonly Dictionary<Type, IValidator> _derivedValidators = new Dictionary<Type, IValidator>();
// Need the base constructor call, even though we're just passing null.
public PolymorphicValidator() : base((IValidator<TInterface>)null, typeof(IValidator<TInterface>)) {
}
public PolymorphicValidator<T, TInterface> Add<TDerived>(IValidator<TDerived> derivedValidator) where TDerived : TInterface {
_derivedValidators[typeof(TDerived)] = derivedValidator;
return this;
}
public override IValidator<TInterface> GetValidator(PropertyValidatorContext context) {
// bail out if the current item is null
if (context.PropertyValue == null) return null;
if (_derivedValidators.TryGetValue(context.PropertyValue.GetType(), out var derivedValidator)) {
return new ValidatorWrapper(derivedValidator);
}
return null;
}
private class ValidatorWrapper : AbstractValidator<TInterface> {
private IValidator _innerValidator;
public ValidatorWrapper(IValidator innerValidator) {
_innerValidator = innerValidator;
}
public override ValidationResult Validate(ValidationContext<TInterface> context) {
return _innerValidator.Validate(context);
}
public override Task<ValidationResult> ValidateAsync(ValidationContext<TInterface> context, CancellationToken cancellation = new CancellationToken()) {
return _innerValidator.ValidateAsync(context, cancellation);
}
public override IValidatorDescriptor CreateDescriptor() {
return _innerValidator.CreateDescriptor();
}
}
}
This will probably be implemented in the library as a first class feature at some point in the future - you can track its development here if you're interested.

Simplest way to mock properties of PostSharp attribute

I'm using a PostSharp method attribute to do authorisation and auditing on my WCF service. It's working properly but now I'm trying to get my unit tests working with the attribute and am struggling to find a way to mock and inject the properties on the attribute.
My attribute is as below.
[Serializable]
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false, Inherited = false)]
public class AuthoriseAndAuditAttribute : OnMethodBoundaryAspect
{
private static ILog logger = AppState.logger;
private static Ninject.IKernel _kernel = MyKernel.Kernel;
private UserRoleTypesEnum _requiredRole = UserRoleTypesEnum.None;
[Inject]
public IServiceAuthToken _serviceAuthToken { get; set; }
[Inject]
public UserSessionDataLayer _userSessionDataLayer { get; set; }
public AuthoriseAndAuditAttribute(UserRoleTypesEnum role = UserRoleTypesEnum.None)
{
_requiredRole = role;
_kernel.Inject(this);
}
public override void OnEntry(MethodExecutionArgs args)
{
// Get the user's session from cookie.
UserSession userSession = GetUserSession();
// Check that user is in the required role.
bool isAuthorised = (_requiredRole == UserRoleTypesEnum.None || (userSession != null && userSession.Roles.Contains(_requiredRole)));
if (!isAuthorised)
{
logger.Warn("Not authorised for " + args.Method.Name + ".");
throw new UnauthorizedAccessException();
}
else if (userSession != null)
{
Thread.CurrentPrincipal = new MyPrincipal(userSession);
}
}
private UserSession GetUserSession()
{
if (_serviceAuthToken != null)
{
string sessionID = _serviceAuthToken.GetSessionID();
if (!sessionID.IsNullOrBlank())
{
return _userSessionDataLayer.GetForSessionID(sessionID);
}
}
return null;
}
}
I have a singleton class setting up the Ninject kernel:
public class MyKernel
{
public static StandardKernel Kernel { get; set; }
static MyKernel()
{
Kernel = new StandardKernel();
Kernel.Bind<IServiceAuthToken>().To<ServiceAuthToken>();
Kernel.Bind<UserSessionDataLayer>().To<UserSessionDataLayer>();
}
}
In my WCF service I use the PostSharp attribute as below:
[AuthoriseAndAudit(UserRoleTypesEnum.Operator)]
public JSONResult<bool> IsAliveAuthorised()
{
return new JSONResult<bool>() { Success = true, Result = true };
}
And in my unit test I'm using RhinoMocks to try and mock the two DI properties in the attribute.
[TestMethod]
public void IsAliveAuthorisedIsAuthorisedTest()
{
var mockServiceAuthToken = MockRepository.GenerateStrictMock<ServiceAuthToken>();
mockServiceAuthToken.Stub(x => x.GetSessionID()).Return("x");
var mockUserSessionDataLayer = MockRepository.GenerateStrictMock<UserSessionDataLayer>();
mockUserSessionDataLayer.Stub(x => x.GetForSessionID(Arg<string>.Is.Anything)).Return(new UserSession());
MyKernel.Kernel.Bind<ServiceAuthToken>().ToConstant(mockServiceAuthToken);
MyKernel.Kernel.Bind<UserSessionDataLayer>().ToConstant(mockUserSessionDataLayer);
var service = new MyService();
Assert.IsTrue(service.IsAliveAuthorised().Result);
}
The issue I have is the mock objects in the unit test are never ending up being set as the properties on the attribute. What am I doing wrong or conversely is there a better way to do unit testing on a PostSharp attribute? Also bearing in mind I really want to minimise the use of the Ninject DI to the bare minimum.
Instead of using the [Inject] attribute on your properties, redefine them like this:
public IServiceAuthToken _serviceAuthToken { get { return _kernel.Get<IServiceAuthToken>(); } }
public UserSessionDataLayer _userSessionDataLayer { get { return _kernel.Get<UserSessionDataLayer>(); } }
Also, in your test method you need to re-bind (note also that you were using the concrete type ServiceAuthToken in the first bind instead of the interface IServiceAuthToken):
MyKernel.Kernel.Rebind<IServiceAuthToken>().ToConstant(mockServiceAuthToken);
MyKernel.Kernel.Rebind<UserSessionDataLayer>().ToConstant(mockUserSessionDataLayer);

Value Injecter : Dto to Domain Model (NHibernate)

I am using ValueInjecter to map properties from a Domain model to a DTO served up via a Service Layer. The service in question also accepts updates... so an updated DTO is passed in and this is then injected to the domain object and saved.
// Domain
public class Member
{
public Country Country { get; set; }
}
public class Country
{
public string Code { get; set; }
public string Name { get; set; }
}
//Dto
public class MemberDto
{
public string CountryCode { get; set; }
}
//Transformation Method attempt 1
public Member InjectFromDto (MemberDto dto, Member source)
{
source = source.InjectFrom<UnflatLoopValueInjection>(dto);
return source;
}
Now all this above code does is updates the Property Member.Country.Code which is obviously not what I need it to do.
So from the docs, I figured I needed to create an override and got this:
public class CountryLookup: UnflatLoopValueInjection<string, Country>
{
protected override Country SetValue(string sourcePropertyValue)
{
return countryService.LookupCode(sourcePropertyValue);
}
}
//revised transformation call
//Transformation Method attempt 2
public Member InjectFromDto (MemberDto dto, Member source)
{
source = source.InjectFrom<UnflatLoopValueInjection>(dto)
.InjectFrom<CountryLookup>(dto);
return source;
}
My problem is during debugging, CountryLookup never gets called.
Possible reasons I can think of:
Nhibernate Proxy classes causing value injecter to not match the Country type? Tho this doesnt make sense because it works during the flattening.
Perhaps the unflattening isn't firing for some reason. I.e Dto is CountryCode and Domain is Country.Code
I need to use the CountryCode property on the Dto to call a countryService.LookupCode to return the correct object to use during the update injection.
unflattening would be to do this:
entity.Country.Code <- dto.CountryCode
what you need is:
entity.Country <- dto.CountryCode
so the solution for you would be to inherit an ExactValueInjection where you would go from CountryCode to Country.
what I recommend you to do is do the same that I did in the live demo of another project of mine http://awesome.codeplex.com
where I have something like this:
public class Entity
{
public int Id{get;set;}
}
public class Member : Entity
{
public Country Country{get;set;}
}
public class MemberDto : DtoWithId
{
public int? Country {get;set;}
}
and use these injections to go from entity to dto and back
public class NullIntToEntity : LoopValueInjection
{
protected override bool TypesMatch(Type sourceType, Type targetType)
{
return sourceType == typeof(int?) && targetType.IsSubclassOf(typeof(Entity));
}
protected override object SetValue(object sourcePropertyValue)
{
if (sourcePropertyValue == null) return null;
var id = ((int?) sourcePropertyValue).Value;
dynamic repo = IoC.Resolve(typeof(IRepo<>).MakeGenericType(TargetPropType));
return repo.Get(id);
}
}
//(you also need to have a generic repository, notice IRepo<>)
public class EntityToNullInt : LoopValueInjection
{
protected override bool TypesMatch(Type sourceType, Type targetType)
{
return sourceType.IsSubclassOf(typeof (Entity)) && targetType == typeof (int?);
}
protected override object SetValue(object o)
{
if (o == null) return null;
return (o as Entity).Id;
}
}
these injections will handle not just going from int? to Country and back but also any other type which inherits Entity
Using the suggestion/reference from Omu this was the specific code to the problem.
public class CountryLookup : ExactValueInjection
{
private ICountryService countryservice;
public CountryLookup(ICountryService countryService)
{
this.countryService = countryService;
}
protected override bool TypesMatch(Type s, Type t)
{
return (s == typeof(string)) && (t == typeof (Country));
}
protected override Object SetValue(object v)
{
if (v == null)
return null;
var country = countryService.LookupCode((string) v);
return country;
}
public override string SourceName()
{
return "CountryCode";
}
public override string TargetName()
{
return "Country";
}
}
public Member InjectFromDto (MemberDto dto, Member source)
{
source = source.InjectFrom<UnflatLoopValueInjection>(dto)
.InjectFrom<CountryLookup>(dto);
return source;
}
Is a framework calling the setter method? In most DI frameworks, the standard is lowercase 's' in the setMethod(). Just a first-thought recommendation.

How to automap a collection of components with Fluent NHibernate?

All of my entities and value objects implement marker interfaces IEntity and IValueObject. I have set them up to be treated as components like so:
public override bool IsComponent(Type type)
{
return typeof(IValueObject).IsAssignableFrom(type);
}
public override bool ShouldMap(Type type)
{
return typeof(IEntity).IsAssignableFrom(type) || typeof(IValueObject).IsAssignableFrom(type);
}
Unfortunately, this does not seem to allow entities that have collections of value objects to be automapped as component collections. For example:
public class MyEntity : IEntity
{
public IList<MyValueObject> Objects { get; set; }
}
public class MyValueObject : IValueObject
{
public string Name { get; set; }
public string Value { get; set; }
}
Is there any way to define a convention such that, any time an IEntity has an IList of a type that implements IValueObject, it gets mapped as if I had specified:
HasMany(x => x.Objects)
.Component(x => {
x.Map(m => m.Name);
x.Map(m => m.Value);
});
What I don't want to do is have to manually do these overrides for every class and write out each property for the value object again and again.
Create a new class that inherits from HasManyStep (FluentNHibernate.Automapping.Steps).
Override the ShouldMap() method with something like :
return base.ShouldMap(member) && IsCollectionOfComponents(member)
Add your logic to :
public void Map(ClassMappingBase classMap, Member member)
{ ... }
Replace the default step with your new one :
public class MyMappingConfiguration : DefaultAutomappingConfiguration
{
public override IEnumerable<IAutomappingStep> GetMappingSteps(AutoMapper mapper, IConventionFinder conventionFinder)
{
var steps = base.GetMappingSteps(mapper, conventionFinder);
var finalSteps = steps.Where(c => c.GetType() != typeof(FluentNHibernate.Automapping.Steps.HasManyToManyStep)).ToList();
var idx = finalSteps.IndexOf(steps.Where(c => c.GetType() == typeof(PropertyStep)).First());
finalSteps.Insert(idx + 1, new MyCustomHasManyStep(this));
return finalSteps;
}
}
Note : You could also get the original source code of HasManyStep.cs and copy it to your project to introduce your custom logic.