I want to make a library that is going to be used and configurable by other people, using akka actors.
I want to make a Repository actor to which a type of storage will be injected by the library user like "MemoryDatabase" or "FileDatabase" or anything that extends a defined class or actor (see question 2).
1) What is the best way for a user to specify options (including his own created ones)?
2) Should "MemoryDatabase" be an actor child of repository, or just a normal class as a field/property of the Repository actor in this case?
Thanks!
-Jojolepro
Edit:
I want to make an actor that looks like
class Repository extends Actor{
val repoType:DataStorageType = ...
def receive:Receive={}
}
What I want to know the best way for a end user of such library to specify the repoType field, considering that Repository is already in a predefined actor hierarchy.
It depends on if you want the user to put in a concrete instance or merely a type. Ignoring any kind of DI system you could use, I would merely pass the concrete instance to the actor's constructor via props when the actor is started but then that would depend on the concrete instance being thread safe because not necessarily only that actor would be managing it. If you want the actor to own the repository, have the user pass the factory instance or type to the props and thus the constructor.
I have a StatefulService with a method. The first argument of the method accepts an interface type that corresponds to one of my Actors. The Actor calls the service method using ServiceProxy, passing this in as the first argument. This compiles file. The signatures match.
When running however, I get an error about an unexpected type of IMyActorType not being known to the DataContractSerializer. I know what this message means. Does ServiceProxy not handle ActorReferences? I know ActorProxy works. I can pass one Actor to another Actor using ActorProxy.
Or is this maybe some problem in my configuration of the StatefulService? Something with my ServiceReplicaListener setup?
I have worked around this issue for now by changing the method signatures of my StatefulService methods to ActorReference. That serializes fine, and I can unpack it on the other side. I would much rather have the proper typing, however.
Service Proxy does not handle the Actor references like Actor Proxy does. Services stack is independent of the actor and does not have knowledge of the actor references. Instead of passing the actor interface, you can pass the actor reference (https://msdn.microsoft.com/en-us/library/azure/microsoft.servicefabric.actors.actorreference.get.aspx) and then bind (https://msdn.microsoft.com/en-us/library/azure/microsoft.servicefabric.actors.actorreference.bind.aspx) the actor reference to the actor interface type on the receiving side. You can cast the output of the binding method to the actor interface.
You need to pass a simple DataContract-decorated POCO and not an interface. DataContractSerializer won't work on an interface. The same rules that would apply for WCF also apply to Service Fabric.
I understand the following Ninject registration:
kernel.Bind<ISomeType>().To<SomeTypeImplementation>();
which tells Ninect to fulfill requests for ISomeType by using SomeTypeImplementation.
However I'm not sure what the following is good for.
kernel.Bind<ApplicationDbContext>().ToSelf();
Which was suggested that I use from this question:
What ninject binding should I use?
It makes ApplicationDbContext "self-bindable". If you don't have an interface to bind to, you can bind to the class itself. It's more useful if you add a scope to the call such as:
kernel.Bind<ApplicationDbContext>().ToSelf().InRequestScope();
Any time it sees the ApplicationDbContext that needs to be injected, it will reuse the same object as long as it is in the same HTTP request.
The default scope is transient, which means that any time a class requests ApplicationDbContext it will create a new instance of it. This can be problematic if you have two classes that both need to use the context in the same transaction. That is why you will often see it done with InRequestScope().
By self-binding a type, you enable that type for the following:
Lifecycle Management by the container.
Enable the container to inject dependencies into other types that depend on the self-bound type, and inject dependencies of this type into its instances likewise.
Very useful if you just have one single implementation or you don't need to use abstractions for some reason.
I have some service methods which return entities that are not implemented yet.
For example, I have an interface called IUser and some classes that implemented this interface such as GuestUser and AdminUser.
All entity classes are well-defined already and I want to use their jar files without manipulating them.
My problem is when I wanted to define ProxyFor IUser.class in client-side entity and to call service methods that their return type are IUser. While calling these methods I get the following error: The domain type com.bis.entity.security.GuestUser cannot be sent to the client.
Is there any way to call methods that deal with interfaces in RequestFactory or do I have to change all the service methods to utilize class entitis?
You have to use classes for now. See http://code.google.com/p/google-web-toolkit/issues/detail?id=5762
I have a question, and I'm going to tag this subjective since that's what I think it evolves into, more of a discussion. I'm hoping for some good ideas or some thought-provokers. I apologize for the long-winded question but you need to know the context.
The question is basically:
How do you deal with concrete types in relation to IoC containers? Specifically, who is responsible for disposing them, if they require disposal, and how does that knowledge get propagated out to the calling code?
Do you require them to be IDisposable? If not, is that code future-proof, or is the rule that you cannot use disposable objects? If you enforce IDisposable-requirements on interfaces and concrete types to be future-proof, whose responsibility is objects injected as part of constructor calls?
Edit: I accepted the answer by #Chris Ballard since it's the closest one to the approach we ended up with.
Basically, we always return a type that looks like this:
public interface IService<T> : IDisposable
where T: class
{
T Instance { get; }
Boolean Success { get; }
String FailureMessage { get; } // in case Success=false
}
We then return an object implementing this interface back from both .Resolve and .TryResolve, so that what we get in the calling code is always the same type.
Now, the object implementing this interface, IService<T> is IDisposable, and should always be disposed of. It's not up to the programmer that resolves a service to decide whether the IService<T> object should be disposed or not.
However, and this is the crucial part, whether the service instance should be disposed or not, that knowledge is baked into the object implementing IService<T>, so if it's a factory-scoped service (ie. each call to Resolve ends up with a new service instance), then the service instance will be disposed when the IService<T> object is disposed.
This also made it possible to support other special scopes, like pooling. We can now say that we want minimum 2 service instances, maximum 15, and typically 5, which means that each call to .Resolve will either retrieve a service instance from a pool of available objects, or construct a new one. And then, when the IService<T> object that holds the pooled service is disposed of, the service instance is released back into its pool.
Sure, this made all code look like this:
using (var service = ServiceContainer.Global.Resolve<ISomeService>())
{
service.Instance.DoSomething();
}
but it's a clean approach, and it has the same syntax regardless of the type of service or concrete object in use, so we chose that as an acceptable solution.
Original question follows, for posterity
Long-winded question comes here:
We have a IoC container that we use, and recently we discovered what amounts to a problem.
In non-IoC code, when we wanted to use, say, a file, we used a class like this:
using (Stream stream = new FileStream(...))
{
...
}
There was no question as to whether this class was something that held a limited resource or not, since we knew that files had to be closed, and the class itself implemented IDisposable. The rule is simply that every class we construct an object of, that implements IDisposable, has to be disposed of. No questions asked. It's not up to the user of this class to decide if calling Dispose is optional or not.
Ok, so on to the first step towards the IoC container. Let's assume we don't want the code to talk directly to the file, but instead go through one layer of indirection. Let's call this class a BinaryDataProvider for this example. Internally, the class is using a stream, which is still a disposable object, so the above code would be changed to:
using (BinaryDataProvider provider = new BinaryDataProvider(...))
{
...
}
This doesn't change much. The knowledge that the class implements IDisposable is still here, no questions asked, we need to call Dispose.
But, let's assume that we have classes that provide data that right now doesn't use any such limited resources.
The above code could then be written as:
BinaryDataProvider provider = new BinaryDataProvider();
...
OK, so far so good, but here comes the meat of the question. Let's assume we want to use an IoC container to inject this provider instead of depending on a specific concrete type.
The code would then be:
IBinaryDataProvider provider =
ServiceContainer.Global.Resolve<IBinaryDataProvider>();
...
Note that I assume there is an independent interface available that we can access the object through.
With the above change, what if we later on want to use an object that really should be disposed of? None of the existing code that resolves that interface is written to dispose of the object, so what now?
The way we see it, we have to pick one solution:
Implement runtime checking that checks that if a concrete type that is being registered implements IDisposable, require that the interface it is exposed through also implements IDisposable. This is not a good solution
Enfore a constraint on the interfaces being used, they must always inherit from IDisposable, in order to be future-proof
Enforce runtime that no concrete types can be IDisposable, since this is specifically not handled by the code using the IoC container
Just leave it up to the programmer to check if the object implements IDisposable and "do the right thing"?
Are there others?
Also, what about injecting objects in constructors? Our container, and some of the other containers we've looked into, is capable of injecting a fresh object into a parameter to a constructor of a concrete type. For instance, if our BinaryDataProvider need an object that implements the ILogging interface, if we enforce IDispose-"ability" on these objects, whose responsibility is it to dispose of the logging object?
What do you think? I want opinions, good and bad.
One option might be to go with a factory pattern, so that the objects created directly by the IoC container never need to be disposed themselves, eg
IBinaryDataProviderFactory factory =
ServiceContainer.Global.Resolve<IBinaryDataProviderFactory>();
using(IBinaryDataProvider provider = factory.CreateProvider())
{
...
}
Downside is added complexity, but it does mean that the container never creates anything which the developer is supposed to dispose of - it is always explicit code which does this.
If you really want to make it obvious, the factory method could be named something like CreateDisposableProvider().
(Disclaimer: I'm answering this based on java stuff. Although I program C# I haven't proxied anything in C# but I know it's possible. Sorry about the java terminology)
You could let the IoC framework inspect the object being constructed to see if it supports
IDisposable. If not, you could use a dynamic proxy to wrap the actual object that the IoC framework provides to the client code. This dynamic proxy could implement IDisposable, so that you'd always deliver a IDisposable to the client. As long as you're working with interfaces that should be fairly simple ?
Then you'd just have the problem of communicating to the developer when the object is an IDisposable. I'm not really sure how this'd be done in a nice manner.
You actually came up with a very dirty solution: your IService contract violates the SRP, wich is a big no-no.
What I recommend is to distinguish so-called "singleton" services from so-called "prototype" services. Lifetime of "singleton" ones is managed by the container, which may query at runtime whether a particular instance implements IDisposable and invoke Dispose() on shutdown if so.
Managing prototypes, on the other hand, is totally the responsibility of the calling code.