How to set a boolean property in NServiceBus MessageHandler through EndPointConfig - properties

I want to set a value to a public boolean property in my NServicebus message handler through EndPoint config.
One way which I know is by creating
An interface with that boolean property.
A concrete class inherited from the interface.
Initializing / Setting the value in that concrete class.
Injecting the concrete class through End-point config.
Is there any other way to achieve this.

Configure.Instance.Configurer
.ConfigureProperty<YourHandlerType>(h => h.BoolProperty,
Bool.Parse(ConfigurationManager.AppSettings["YourSetting"]));
In future versions, this will be even easier.
Edit:
You can try registering late with IWantToRunBeforeConfigurationIsFinalized, as suggested by David.
You can also register the component early. Since NServiceBus registers handlers as DependencyLifecycle.InstancePerUnitOfWork, your code should be doing the same
Configure.Component<YourHandlerType>(DependencyLifecycle.InstancePerUnitOfWork)
.ConfigureProperty(h => h.BoolProperty,
Bool.Parse(ConfigurationManager.AppSettings["YourSetting"]));

Related

asp.net core dependency injection issue - AddScoped not creating a new instance

I've been using asp.net core dependency injection and I have seen an not expected behavior, at least for me. I'm adding a new service to the container like this:
services.AddScoped<IMyClass>(provider =>
{
return new MyClass(
"anyValue"
});
After that, I inject the class into another class to use it:
public class AnotherClass(IMyClass xxx){
}
The thing is that there are a couple configurations that are made on the MyClass constructor based on request information. The problem is that I've seen the MyClass constructor be executed at the application startup only. After that, the class seems to use the same instance for all calls. As I'm using Scoped service I'm expecting to have a new instance for each request, am I wrong?
Thanks.
Ok. The problem was that the class that was receiving the injection was added to the container as singleton. I just changed it to Scoped and everything worked well.
Thanks!

Ninject - Resolve instance per method call

I'm finding a solution to resolve an instance per method call.
Something like that:
public class ServiceAPI
{
public void ServiceAction()
{
//Call certain repository action
// Ex:
Kernel.Get<RepositoryA>().Insert();
}
}
public class RepositoryA
{
public void Insert(object a)
{
//Get logger per service call ?
var logger = Kernel.Get<RepositoryA>().Insert();
}
}
I wanna the logger instance created one time per service call and it will be used throughout the repository.
I try with Ninject.Extensions.NamedScope extensions but it haven't worked yet.
Can you have any way to deal with this scenario ?
It is not possible to achieve this by using a scoping mechanism. (InCallScope(), InNamedScope(...),...).
Scoping is only relevant when ninject is calling the constructor of a type.
Ninject cannot - ever - replace the instance that is already passed to an object.
If you want to do this you have to program it yourself.
Here's two design alternatives how you can achieve what you want:
instantiate an object tree per method invocation. If there's some service infrastructure like WCF or Web-API there are probably hooks which can be used to do so.
replace the object which should be instantiated per method call by a proxy. The proxy can then use Ninject to create the target for each method call and execute the method on it.
For proxying you can use tools like Castle DynamicProxy or LinFu. There's also Ninject.Extensions.Interception which may also be helpful.

Ninject Conditional injection problems

I have the following bindings declared
Bind<IDataSource>().To<DataSourceOne>();
Bind<ISettings>().To<DataSourceSettings>
.WhenInjectedInto<DataSourceOne>();
Bind<ISettings>().To<Settings>();
now I call
Kernel.Get<IDataSourc>();
Ninject correctly injects a DataSourceSettings, but I need to pass a constructor argument to Settings and DataSourceSettings based on data from a config file. so I've changed the IDataSouce binding as follows
Kernel.Bind<IDataSource>().To<DataSourceOne>()
.WithConstructorArgument("settings", Kernel.Get<ISettings>(
new ConstructorArgument("data", objectContainingConfigFileData)
)
);
in that case Ninject injects Settings class instead of DataSourceSettings class. I assume the problem is that the ISettings is getting resolved before it is injected into the DataSourceSettings class so Ninject does not use the binding I intended it to. Is there a way to get around this. I haven't found anything yet.
It should work if you define the constructor argument for the ISettings binding and not for the DataSource binding. Assuming you already know the object with the config file data in the module. Otherwise maybe a factory would be more appropriate.
kernel.Bind<IDataSource>().To<DataSourceOne>();
kernel.Bind<ISettings>().To<DataSourceSettings>()
.WhenInjectedInto<DataSourceOne>()
.WithConstructorArgument("data", objectContainingConfigFileData);
kernel.Bind<ISettings>().To<Settings>();

How does the Ihttphandler interface expose the httpcontext object

Hello I see on msnd that anything that inherits from the Ihttphandler interface has access to a httpcontext object (under the remarks section of the page in below link)
msdn HTTPContext
My question is how does the interface expose this object...I don't see any property of type httpcontext in the interface. I do see the "ProcessRequest" method that is taking in an httpcontext object. But i'm not seeing how that is resulting in the httpcontext object being exsposed directly from the interface as the msnd page says.
Forgive me if i'm missing a key concept here, fairly new to this. Thanks
No, it is passed into the ProcessContext method only. The handler then interacts with that HttpContext instance as it's the context for the request. You can pass around the context instance to various other methods and such as much as you would like.
Why it is done this way becomes more clear if you look at the documentation about the IsReusable property. When that property is true, multiple requests can be served by the same handler instance, and thus they must be supplied a separate HttpContext to work.
Now, if you specify IsReusable as false, you can then store the HttpContext instance from ProcessRequest in a property on the instance. Not sharing the handler can cause performance issues under some scenarios, but you likely won't need to worry about that.

Can a custom UserNamePasswordValidator add things to the WCF session?

Related to this question, I'm instantiating a connection to our internal API inside my custom UserNamePasswordValidator. Can I stash this somewhere so that I can use it in future calls in that user's session?
This is similar to this question, but I'm not using IIS, so I can't use HttpContext.Current (or can I?).
Update: Some context: our internal API is exposed via a COM object, which exposes a Login method. Rather than have a Login method in my service interface, I've got a custom UserNamePasswordValidator, which calls the Login method on the COM object.
Because instantiating the COM object and logging in is expensive, I'd like to re-use the now-logged-in COM object in my service methods.
Yes, it can. You'll need:
a custom ServiceCredentials implementation that returns a custom SecurityTokenManager.
a custom SecurityTokenManager implementation that returns a custom CustomUserNameSecurityTokenAuthenticator.
your custom CustomUserNameSecurityTokenAuthenticator needs to override ValidateUserNamePasswordCore, and should add a custom implementation of IAuthorizationPolicy.
your implementation of IAuthorizationPolicy should implement Evaluate, at which point it can start putting things in the WCF context.
replace the evaluationContext["PrimaryIdentity"] value with a PasswordIdentity or a custom IIdentity.
replace the evaluationContext["Principal"] value with a PasswordPrincipal or a custom IPrincipal.
update the evaluationContext["Identities"] collection to replace the GenericIdentity instance with your custom instance.
By doing this, you can have a custom IPrincipal implementation with some extra information in it.
For more details, see this.
UserNamePasswordValidator is absolutely out of all WCF contexts. It is only used to validate user name and password. Can you futher explain your problem?
Edit:
I guess COM object is instantiated for each session, isn't it? Otherwise wrapping COM into singleton should solve your problem. If you need to have per session COM object shared between validator and service instance you will need some cache or registry - something which is outside both validator and service and can be called from both of them.