问题
I'll expose what I'm doing now, and later, what I'd like to do using NInject.
Classes:
- Kernel,
- ApiClient
- IIdentity
Kernel exposes several methods as:
object method(IIdentity identity)
-----------------------
public List<Domain.Channel> getChannels(Domain.Identity.IIdentity identity) {...}
Kernel contains several identities stored, and according each context I need to do a thing or another. In this case, my context is inside the method and the context key is identity parameter value. According this one, I need to get an instance of ApiClient.
Actually, I'm doing this using a Dictionary property of Kernel class:
private Dictionary<Domain.Identity.IIdentity, LEST.Client.ApiClient> lests;
And then I initialize.
foreach (Domain.Identity.IIdentity identity in this.identities)
{
LEST.Client.ApiClient lest = new LEST.Client.ApiClient();
lest.configure(identity.ClientId, identity.Username, identity.Password);
this.lests.Add(identity, lest);
}
So, when I need to get a concrete ApiClient object according an identity:
public List<Domain.Channel> getChannels(Domain.Identity.IIdentity identity)
{
LEST.Client.ApiClient current_lest;
this.lests.TryGetValue(identity, out current_lest);
if (current_lest != null)
{
...
}
I'd like to do it using NInject. I've created a module in order to create the bindings to itselfs. The problem is that I've no idea how to create a custom context like this.
I'll appreciate a lot your help.
Thanks for all.
EDIT
I've abstracted a basic Core class that summarizes my explanation.
public class Core
{
private IList<IIdentity> identities;
private Ninject.IKernel kernel;
public Core()
{
this.identities = new List<IIdentity>();
}
public void initialize()
{
this.kernel = new Ninject.StandardKernel(new LestModule());
}
public void openSession(IIdentity identity)
{
ApiClient client = this.kernel.Get<ApiClient>();
}
public void doSomething(IIdentity identity)
{
ApiClient client = this.kernel.Get<ApiClient>();
client...
}
public void closeSession(IIdentity identity)
{
ApiClient client = this.kernel.Get<ApiClient>();
this.kernel.Release(client);
}
}
And the module is:
public class LestModule : Ninject.Modules.NinjectModule
{
public override void Load()
{
this.Bind<ApiClient>().ToProvider(new CustomProvider());
this.Bind<IIdentity>().To<Identity>();
}
}
public class CustomProvider : IProvider<ApiClient>
{
public object Create(IContext context)
{
//context data???
// How to obtain current IIdentity on here?
object d = context;
return new ApiClient("", "", "");
}
public System.Type Type
{
get { return typeof(ApiClient); }
}
}
And the abstraction of ApiClient
public class ApiClient
{
private string username;
public string Username
{
get { return username; }
set { username = value; }
}
private string client_id;
public string ClientId
{
get { return client_id; }
set { client_id = value; }
}
private string passwd;
public string Passwd
{
get { return passwd; }
set { passwd = value; }
}
public ApiClient(string client_id, string username, string password)
{
this.client_id = client_id;
this.username = username;
this.passwd = password;
}
}
So, I'd like that:
- In openSession: Create a ApiClient instance (this.kernel.Get) initializing the instance according the IIdentity param of this method.
- In doSomething: Get a ApiClient instance according the IIdentity param of this method.
- In closeSession: Realise the instance according the IIdentity param of this method.
回答1:
I've implemented this.
It's working now.
public class LestModule : Ninject.Modules.NinjectModule
{
public override void Load()
{
this.Bind<LEST.Client.ApiClient>().ToProvider<LEST.Client.ApiClient>(new ApiClientProvider());
}
}
public class ApiClientProvider : Ninject.Activation.IProvider<LEST.Client.ApiClient>
{
private System.Collections.Generic.Dictionary<Domain.Identity.LESTIdentity, LEST.Client.ApiClient> lests;
public ApiClientProvider()
{
this.lests = new System.Collections.Generic.Dictionary<Domain.Identity.LESTIdentity, LEST.Client.ApiClient>();
}
public object Create(Ninject.Activation.IContext context)
{
Ninject.Parameters.IParameter identity_parameter = context.Parameters.FirstOrDefault(p => p.Name == "identity");
Domain.Identity.LESTIdentity identity = (Domain.Identity.LESTIdentity)identity_parameter.GetValue(context, null);
LEST.Client.ApiClient current_client = null;
this.lests.TryGetValue(identity, out current_client);
if (current_client == null)
{
current_client = new LEST.Client.ApiClient();
current_client.configure(...);
this.lests.Add(identity, current_client);
}
return current_client;
}
...
}
In order to get the instance according to the identity:
public void createChannel(Domain.Identity.ClientIdentity client_identity, Domain.Identity.UserIdentity user_identity, Domain.Channel channel)
{
LEST.Client.ApiClient client = NinjectServiceLocator.Instance.Kernel.Get<LEST.Client.ApiClient>(new Ninject.Parameters.Parameter("identity", new Domain.Identity.LESTIdentity(user_identity.Id, user_identity.Name, client_identity.Id, client_identity.Name), true));
client.ChannelsApiP.Create(AutoMapper.Mapper.Map<Domain.Channel, LEST.Model.ChannelDTO>(channel));
}
What do you thing about?
来源:https://stackoverflow.com/questions/31476018/ninject-custom-context