Ninject - Resolve instance per method call - ninject

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.

Related

How to pass a runtime parameter as part of the dependency resolution for a generic class?

A similar question has been answered here:
How can I pass a runtime parameter as part of the dependency resolution?
However, I was wondering how this can be done when registering a generic class?
Normally, I would register it as following:
services.AddScoped(typeof(ITest<>), typeof(Test<>));
But what if I want to pass a runtime parameter to constructor? Without using DI, it would be something like:
new Test<MyClass>(string mystring, int myInt)
In the linked answer it's suggests using a factory method but this is giving me an error if I don't pass it the exact type.
The alternative would be to get an instance without passing a runtime parameter in the constructor and instead using a setter method after getting exact instance. I would like to avoid this however because every time after getting instance you must remember to call setter method.
Is there some way around it? I guess I could use some factory class instead of registering it in startup class...
EDIT:
After reading Steven's answer which was very useful, I updated question with more concrete example:
Following example is inside some method:
//instance of repository are passed inside constructor of class
//calling some to update/insert
//IMPORTANT - calling external service I want save parameters to db no matter what
using(var ctx=new DbContext())
{
//create log object
ctx.logs.add(Obj)
ctx.save()
}
//some code after
Let's say I want to be consistent and call method of my loggingrepository and there add logging object and save everything to database
However, every repository in constructor accepts DbContext, which is registered as scoped (durig one request).
If it's inside transaction, saving depends about code after calling external service and it can throw exception and save nothing.
So yeah, I could create new dbContext and pass it in logging method or call some private logging function and save inside it,
but point is that if I would ask for instance of loggingRepository I would want DI to pass this localy created dbContext variable to constructor
and not one registered as scoped inside startup method, so that addind and saving log happens no matter what external service or code after calling it does.
My situation in something similar, but it's going for some data in db based on current user and I don't wanna pass same parameter to numerous method, but only inside class constructor.
The general solution in injecting primitive configuration values into your application components, is to extract them into a Parameter Object. This gives those values a new, unambiguous type, which can be registered into your container:
// Parameter Object
public TestConfiguration
{
public string Mystring;
public int MyInt;
}
// (Generic) class using the Parameter Object
public class Test<T>
{
public Test(TestConfiguration config) { ... }
}
// Registering both
services.AddScoped(typeof(ITest<>), typeof(Test<>));
services.AddSingleton(new TestConfiguration { Mystring = ..., Myint = ... });
Configuration values are not considered to be runtime data as their values are known at startup and constant for the duration of the application. That's why you can supply them to the constructors of your application components.
Real runtime data, however, should not be passed on to a component during construction. Runtime data are values that are not known at startup and typically passed along by the user through a web request, are retrieved from the database, session, or anything that can change during the lifetime of the application.
Instead of passing runtime data in through the constructor, you should either:
Pass runtime data through method calls of the API or
Retrieve runtime data from specific abstractions that allow resolving runtime data.
You can find more information about passing runtime data here.

Authentication for Apache Ignite 2.5

I would like to implement authentication for all the nodes of the cluster (client and server should provide username and password to join the cluster). I tried to use the latest version, which the documentation claims to provide authentication, but it doesn't implement it for all the nodes; it's just for the new thin java client.
First question: is my understanding correct, or am I missing something?
I also tried to implement the authentication of all the nodes using the GridSecurityProcessor interface, as part of a custom plugin (by following this guide http://smartkey.co.uk/development/securing-an-apache-ignite-cluster/ and other discussions on the public mailing list).
I got the plugin to be recognized by the server node, but I can't wire my implementation of the SecurityCredentialsProvider to Ignite; it seems Ignite doesn't use it. The question is similar to this one: http://apache-ignite-users.70518.x6.nabble.com/Custom-SecurityCredentialsProvider-and-SecurityCredentials-td16360.html.
As a consequence, when GridSecurityProcessor.authenticateNode(ClusterNode node, SecurityCredentials cred) is called, cred is null.
Second question: How to hook SecurityCredentialsProvider and SecurityCredentials to Ignite, so that it will call the authorizeNode method from my plugin, with these credentials?
I managed to implement authentication with using the plugin system recommended by the documentation. I followed these steps:
Created a class extending the TcpDiscoverySpi and implements DiscoverySpiNodeAuthenticator. In it I pass the SecurityCredentials object as a constructor parameter.
`
public CustomTcpDiscoverySpi(final SecurityCredentials securityCredentials) {
this.securityCredentials = securityCredentials;
this.setAuthenticator(this);
}
In this class, I override the setNodeAttributes from TcpDiscoverySpi to add the securityCredentials object like this:
`
#Override
public void setNodeAttributes(final Map<String, Object> attrs, final IgniteProductVersion ver) {
attrs.put(IgniteNodeAttributes.ATTR_SECURITY_CREDENTIALS, this.securityCredentials);
super.setNodeAttributes(attrs, ver);
}
I also implement the authenticateNode method where I check the SecurityCredentials object of this class with the one received as a parameter on the authenticateNode method. This method returns an implementation of SecurityContext if authentication succeeded or null if not; so you need to implement it as you like. For example to give full access with no authorization, just return true for all the ****operationAllowed methods and return null in subject() method.
In IgniteConfiguration, use this class as discoverySpi: cfg.setDiscoverySpi(customTcpDiscoverySpi);

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!

IQueryable Repository with StructureMap (IoC) - How do i Implement IDisposable?

If i have the following Repository:
public IQueryable<User> Users()
{
var db = new SqlDataContext();
return db.Users;
}
I understand that the connection is opened only when the query is fired:
public class ServiceLayer
{
public IRepository repo;
public ServiceLayer(IRepository injectedRepo)
{
this.repo = injectedRepo;
}
public List<User> GetUsers()
{
return repo.Users().ToList(); // connection opened, query fired, connection closed. (or is it??)
}
}
If this is the case, do i still need to make my Repository implement IDisposable?
The Visual Studio Code Metrics certainly think i should.
I'm using IQueryable because i give control of the queries to my service layer (filters, paging, etc), so please no architectural discussions over the fact that im using it.
BTW - SqlDataContext is my custom class which extends Entity Framework's ObjectContext class (so i can have POCO parties).
So the question - do i really HAVE to implement IDisposable?
If so, i have no idea how this is possible, as each method shares the same repository instance.
EDIT
I'm using Depedency Injection (StructureMap) to inject the concrete repository into the service layer. This pattern is followed down the app stack - i'm using ASP.NET MVC and the concrete service is injected into the Controllers.
In other words:
User requests URL
Controller instance is created, which receives a new ServiceLayer instance, which is created with a new Repository instance.
Controller calls methods on service (all calls use same Repository instance)
Once request is served, controller is gone.
I am using Hybrid mode to inject dependencies into my controllers, which according to the StructureMap documentation cause the instances to be stored in the HttpContext.Current.Items.
So, i can't do this:
using (var repo = new Repository())
{
return repo.Users().ToList();
}
As this defeats the whole point of DI.
A common approach used with nhibernate is to create your session (ObjectContext) in begin_request (or some other similar lifecycle event) and then dispose it in end_request. You can put that code in an HttpModule.
You would need to change your Repository so that it has the ObjectContext injected. Your Repository should get out of the business of managing the ObjectContext lifecycle.
I would say you definitely should. Unless Entity Framework handles connections very differently than LinqToSql (which is what I've been using), you should implement IDisposable whenever you are working with connections. It might be true that the connection automatically closes after your transaction successfully completes. But what happens if it doesn't complete successfully? Implementing IDisposable is a good safeguard for making sure you don't have any connections left open after your done with them. A simpler reason is that it's a best practice to implement IDisposable.
Implementation could be as simple as putting this in your repository class:
public void Dispose()
{
SqlDataContext.Dispose();
}
Then, whenever you do anything with your repository (e.g., with your service layer), you just need to wrap everything in a using clause. You could do several "CRUD" operations within a single using clause, too, so you only dispose when you're all done.
Update
In my service layer (which I designed to work with LinqToSql, but hopefully this would apply to your situation), I do new up a new repository each time. To allow for testability, I have the dependency injector pass in a repository provider (instead of a repository instance). Each time I need a new repository, I wrap the call in a using statement, like this.
using (var repository = GetNewRepository())
{
...
}
public Repository<TDataContext, TEntity> GetNewRepository()
{
return _repositoryProvider.GetNew<TDataContext, TEntity>();
}
If you do it this way, you can mock everything (so you can test your service layer in isolation), yet still make sure you are disposing of your connections properly.
If you really need to do multiple operations with a single repository, you can put something like this in your base service class:
public void ExecuteAndSave(Action<Repository<TDataContext, TEntity>> action)
{
using (var repository = GetNewRepository())
{
action(repository);
repository.Save();
}
}
action can be a series of CRUD actions or a complex query, but you know if you call ExecuteAndSave(), when it's all done, you're repository will be disposed properly.
EDIT - Advice Received From Ayende Rahien
Got an email reply from Ayende Rahien (of Rhino Mocks, Raven, Hibernating Rhinos fame).
This is what he said:
You problem is that you initialize
your context like this:
_genericSqlServerContext = new GenericSqlServerContext(new
EntityConnection("name=EFProfDemoEntities"));
That means that the context doesn't
own the entity connection, which means
that it doesn't dispose it. In
general, it is vastly preferable to
have the context create the
connection. You can do that by using:
_genericSqlServerContext = new GenericSqlServerContext("name=EFProfDemoEntities");
Which definetely makes sense - however i would have thought that Disposing of a SqlServerContext would also dispose of the underlying connection, guess i was wrong.
Anyway, that is the solution - now everything is getting disposed of properly.
So i no longer need to do using on the repository:
public ICollection<T> FindAll<T>(Expression<Func<T, bool>> predicate, int maxRows) where T : Foo
{
// dont need this anymore
//using (var cr = ObjectFactory.GetInstance<IContentRepository>())
return _fooRepository.Find().OfType<T>().Where(predicate).Take(maxRows).ToList();
And in my base repository, i implement IDisposable and simply do this:
Context.Dispose(); // Context is an instance of my custom sql context.
Hope that helps others out.

How do I pass a service to another plugin?

I have a plugin that I will instantiate at runtime and I want to pass it a WCF service from the application host. The application host is responsible for creating the connection to the service. The reason for this is that a single service can be used by multiple plugins, but the plugins should only know about its interface since there may be several implementation of IMyPluginServices. For instance, the Run method of the plugin instance would be:
public void Run(IMyPluginServices services)
{
services.DoSomething();
}
The problem I am running into is that I don't know how to create a service of type IMyPluginServices and pass it to the Run function. The service reference generated by VS 2010 doesn't seem to create an object of type IMyPluginServices that I can pass to it. Any help would be greatly appreciated. Thanks.
When you add a service reference in VS 2010 for a service it generates an interface named IMyService which contains methods for each OperationContract in your service. It also generates a concrete class named MyServiceClient, which can be constructed and then used to invoke your service.
Now, the problem that you're running into, I believe, is that MyServiceClient is a subclass of ClientBase<IMyService>, and does not implement the generated IMyService interface (which is a real pain).
To get around this problem I ended up making a new interface:
public interface IMyServiceClient : IMyService, IDisposable, ICommunicationObject
{
}
(Note: IDisposable and ICommunicationObject are only required if you want your module to be able to detect/react to faulted channels and other such things).
I then extend MyServiceClient with a partial class (in the assembly that contains my WCF Service reference):
public partial class MyServiceClient : IMyServiceClient
{
}
Now in my modules I can accept an IMyServiceClient instead of an IMyService, and still execute all of the methods that I need to. The application in control of the modules can still create instances of MyServiceClient as it always did.
The beauty of this is that your new interface and partial class don't need any actual code - the definitions suffice to get the job done.