StructureMap grouping of named instances - wcf

Long post - sorry....
I'm doing input validation for a WCF service and using StructureMap IoC to instantiate the appropriate validation objects.
I have 2 different validation groups:
Per object validation: means that one input parameter, will be resolve by the Ioc (e.g. Ioc.ResolveAll<IValidatorObject<InputParameter1>, .... <InputParameter2>... etc). If any rules are found, the validate method is invoked.
Per context validation: mean that validation rules are invoked, based on the current context (explicit roles). A context could be 'deposit money' or 'open bank account'. Context validation are usually dependent on 2 or more of the input parameters and is the key difference between object and context validation.
The input validation is performed in the BeforeCall event call in the IParameterInspector (provider/server side!). With this event I get a string containing the operation name (aka. the context) and an object[] with the input parameters.
The problem is that there's multiple validation rules for a single context and the only way I have figured out to register the context in the Ioc, is by using named intances. However I can only register 1 named instance pr. interface. And the interface is not uniquely identifiable by its signature. E.g.
Context rule for 'create account': IValidatorContext<User, Account>
Context rule for 'deposit money': IValidatorContext<User, Account>
So my question is, whether it is possible to register the context in StructureMap in any other way than named instances - or maybe a way to group named instances.
An alternative route, is to implement explicit interfaces for each context, so that the DepositMoney service method might look like this:
public Response Deposit(IDepositMoney inputArguements)
where IDepositMoney contains the input parameters.
So am I way off here, or can I somehow register a context in StructureMap? Or should I just go ahead and use explicit interface instead (3rd option?)
Thanks in advance

Ended up wrapping each set of input parameters in a context and used the context to register in StructureMap. Works like a charm!

The whole idea of named instances is that the name points to a single instance, so you won't be able to use that feature to do what you are trying to achieve. I would use explicit interfaces, since this will allow you to auto wire more things and have less calls to your container.

Related

Ninject provider can't resolve types registered within a named scope

I am using the NamedScoped Ninject extension in an attempt to create object graphs that are constructed everytime a command handler is constructed by the container. In other words, I want a fresh object graph for every command that might get processed by its corresponding handler.
I have used the .DefinesNamedScope("TopLevelOrhcestrator") binding when registering my "command handlers" as they are the top level for command processing.
A type in this named scope needs to be injected with the result of a method call on a type already registered in this named scope. I thought the best way to do this would be with a ninject provider.
Inside the provider I attempt to resolve the type in hopes I can call a method on it to pass into another object I am creating within this named scope. The problem I'm having is that when I ask the IContext for the instance inside the customer provider I get an exception that says "No matching scopes are available, and the type is declared InNamedScope(TopLevelOrchestrator).
context.Kernel.Get<TypeAlreadyRegisteredInScope>().MethodThatGetsAnotherDependency()
Is it possible to get types from the container inside a Ninject provider when they are registered inside a named scope?
EDIT
I apologize if the use case seems a bit odd, I am experimenting with some ideas about how to manage my units of work and other services/managers that may need a handle to the uow to complete a business usecase. I know its common for the unit of work to be "started" and then passed into all dependencies that may need to take part in a larger process. I was thinking I'd rather let my orchestrator take a unit of work factory so that it could deterministically destroy the UOW and it would be clear who the owner of a usecase is. What would get supplied to the managers/services would be a proxy to the unit of work that would be null until a real unit of work was started by the orchestrator. That's why I was attempting to link the proxy from the already registered type in my provider. This is all very experimental at this point and was testing some ideas.
I'd be happy to hear any further thoughts.
For MethodThatGetsAnotherDependency() to be able to .Get<>() an instance that is bound .InNamedScope(...) you will need to add the Context Preservation Extension.
This is because NamedScope is adding a parameter to the request context of the binding that has .DefinesNamedScope(...). As soon as that request is over, that context and it's parameters are forgotten. Now with the ContextPreservation extension the context is kept and reused for late / factory creations (Func<>, interface factory with .ToFactory() binding...). It think it should also work with providers.
If not, just switch to a factory instead of a provider.
However i have to admit that i don't fully understand why/what you are trying to achieve. There might be simpler ways.

Intercepting object creation in RavenDb

I am trying to run some code on objects that are loaded from RavenDB, and I need to do it just after the object has been loaded with its property values.
I've tried intercepting the deserialization process using a CustomCreationConverter and overriding ReadJson, but the object I can access at that point has all the properties set, except the one I need : the Id. Is there somewhere else I can slot into the pipeline in order to do this?
The reason you don't see the Id is because it's not part of the document, it's in the metadata as #id.
If you want to intercept client side, you can register a custom Conversion Listener. Create a class that implements IDocumentConversionListener and register it with documentStore.RegisterListener(). In the DocumentToEntity method, you can run your custom logic. The documentation is lacking on Listeners in general, but there is another topic that also uses them:
http://ravendb.net/kb/16/using-optimistic-concurrency-in-real-world-scenarios
The other option would be to add a bundle that intercepts on the server side. For that, you would use a Read Trigger.

Generic DataContract in Agatha WCF

I am trying to use Generic DataContract class so that I don't have to implement several types for a collection of different objects.
Exp :
I have a Profile object which contains a collection of objects.
So I want to have one Profile<Foo> and Profile<Foo1> where profile contains a collection of Foo or Foo1 objects.
I have been reading that WCF does not support generic classes and actually the error that I get is the following.
Type 'GL.RequestResponse.ProfileResponse1[T]' cannot be exported as a schema type because it is an open generic type. You can only export a generic type if all its generic parameter types are actual types.`
Now the ProfileResponse is this Profile object that I am trying to use.
Now in my host I am doing the following. :
ServiceConfig(typeof(ProfileHandler<EducationResponse>).Assembly,
typeof(ProfileRequest).Assembly,
typeof(Container)).Initialize();
This is dhe definition of the handler with the datacontract.
public class ProfileHandler<T> : RequestHandler<ProfileRequest,
ProfileResponse<T>>
The Container is using Windsor Container to register the objects.
The registration works fine but after I instantiated the Service Host for WCF processor, and call Open Method of the host I get the above error.
Is there really no way for me to write generic response requests for wcf with agatha ?
It feels like such a waste to have to define a Profile container class for each type being contained in that collection.
thanks.
One cannot have open generic handlers, because the server side needs to know what the type is.
One can use so called closed generic methods. This way the server side knows the types for witch to load the handler.
Also, one could potentially configure Agatha so that it allows to receive extra information related to the request. In this case, it would be the type wrapped in the response.
One could do this by defining a a BaseRequest class and having all the request extend this class. This class can have a property which takes the type of the response. Or the type to be wrapped in the response.
In the process, when examining the request, the process can get the type to be wrapped in the Response, so that i knows how to load the class.
I have not implemented this, since it would take too much time and I am not sure I want to be responsible for maintaining Agatha for our application, but this is how I would do it.

Inject behavior into WCF After or During identification of WebGet Method to call

I am trying to solve a problem where i have a WCF system that i have built a custom Host, Factory host, instance providers and service behaviors to do authentication and dependency injection.
However I have come up with a problem at the authorisation level as I would like to do authorisation at the level of the method being called.
For example
[OperationContract]
[WebGet(UriTemplate = "/{ConstituentNumber}/")]
public Constituent GetConstituent(string ConstituentNumber)
{
Authorisation.Factory.Instance.IsAuthorised(MethodBase.GetCurrentMethod().Name, WebOperationContext.Current.IncomingRequest.Headers["Authorization"]);
return constituentSoapService.GetConstituentDetails(ConstituentNumber);
}
Basically I now have to copy the Call to IsAuthorised across every web method I have. This has two problems.
It is not very testable. I Have extracted the dependecies as best that I can. But this setup means that I have to mock out calls to the database and calls to the
WebOperationContext.
I Have to Copy that Method over and over again.
What I would like to know is, is there a spot in the WCF pipeline that enables me to know which method is about to be called. Execute the authorisation request. and then execute the method based on the true false value of the authorisation response.
Even better if i can build an attribute that will say how to evaluate the method.
One possible way to do what you want might be by intercepting requests with a custom IDispatchMessageInspector (or similar WCF extension point).
The trick there, however, is that all you get is the raw message, but not where it will be processed (i.e. the method name). With a bit of work, however, it should be possible to build a map of URIs/actions and the matching method names (this is how you'd do it for SOAP, though haven't tried it for WebGet/WebInvoke yet).

In Ninject 2.0, how do I have both a general binding and a binding for a specific case?

I have a situation where I want to dependency inject my user object, but also place the current user in the IoC container. I want the following lines to work:
kernel.Get<User>(); // Should return a new User()
kernel.Get<User>("Current"); // Should return the current user
One might think bindings like this would work:
Bind<User>().ToSelf();
Bind<User>().ToMethod(LoadCurrentUser).InRequestScope().Named("Current");
Of course, that gives:
Ninject.ActivationException: Error activating User
More than one matching bindings are available.
Activation path:
1) Request for User
Suggestions:
1) Ensure that you have defined a binding for User only once.
I understand the error since a Named binding does not restrict the application of that binding, so both bindings apply. It seems clear that I need to use the contextual bind with the .When*() methods but I can't come up with any way to do that. I feel like there should be when methods that detect whether a named instance is applied. Something like:
// Not valid Ninject syntax
Bind<User>().ToSelf().WhenUnnamedRequested();
Bind<User>().ToMethod(LoadCurrentUser).WhenNamedRequested().InRequestScope().Named("Current");
I can't find any place on the IRequest interface or it's properties that tells me the name requested. How do I do this?
This question was answerd on the mailing list:
http://groups.google.com/group/ninject/browse_thread/thread/cd95847dc4dcfc9d?hl=en
If you are accessing the user by calling Get on the kernel (which I hope you do not) then give the first binding a name as well and access User always by name. Actually, there is a way to get an instance from the binding without a name. But because I heartily recommend not to do this, I do not show how to to this here. If you still want to do it this way I'll tell you later how this would work.
If you are doing it the better and prefered way and inject the user to the objects that require it as dependency there are two options:
The easier one: Give the first binding a name and add a named attribute to the parameters e.g. ctor([Named("NewUser") IUser newUser, [Named("Current")] IUser
currentUser)
Or the prefered way to keep the implementation classes free of the IoC framework: Specify custom attributes and add them to the parameters e.g. ctor([NewUser] IUser newUser, [CurrentUser]IUser currentUser). Change the Bindings to:
Bind<User>().ToSelf()
.WhenTargetHas<NewUserAttribute>();
Bind<User>().ToMethod(LoadCurrentUser)
.InRequestScope()
.WhenTargetHas<CurrentUserAttribute>();