ServiceStack, how to access business logic Pocos? - c#

Given the following service class in ServiceStack,
public class HelloWorldService: Service
{
public string Get(HelloWorldRequest request)
{
return someOtherClassInstance;
}
}
how would I access someOtherClassInstance? I am puzzled about what best practices are to return objects in specific states? I understand its easy to access static class objects from within HelloWorldService but how about other instances that hold state? I feel extremely hard pressed to believe the best solution is IoC. Any better ways? How can I pass in references to be used? Any suggestions and ideas?
Thanks a lot!

You're over thinking this. A Service in ServiceStack is just a plain C# instance that gets initiated and populated on every request.
By default the built-in Funq registers everything as a singleton, so when you register an instance e.g:
container.Register(new GlobalState());
and reference it in your Service:
public class HelloWorldService: Service
{
public GlobalState GlobalState { get; set; }
public string Get(HelloWorld request)
{
return GlobalState.SomeOtherClassInstance;
}
}
behind the scenes it's always injecting the same instance, and in Funq this is very fast since it's literally just retrieving the instance from an in-memory Dictionary.
But if for whatever reason you don't like that approach than as a Service is still just a C# class so you can use a static property:
public class HelloWorldService: Service
{
public static GlobalState GlobalState = new GlobalState { ... };
public string Get(HelloWorld request)
{
return GlobalState.SomeOtherClassInstance;
}
}
or a Singleton:
public class HelloWorldService: Service
{
public string Get(HelloWorld request)
{
return GlobalState.Instance.SomeOtherClassInstance;
}
}
or however else you want to do it. I recommend using an IOC since it's more testable and consistent with how all other dependences are registered, and I don't really see a good reason not to.

Related

Locate different generic services in one non generic Locator

I have various Services that implement
public interface IReceiver<PayLoad>
{
string Name {get;}
Task SendObjectContainerAsync(ObjectContainer<PayLoad> m);
Task<ObjectContainer<PayLoad>> GetSnapshot();
}
For Example
public class Printer : IReceiver<TextDocument>
or
public class TextDocumentService : IReceiver<Letter>
Now I want to collect all instances of each IReceiver in one Controller, I could
public class Broker<Payload>
{
List<IReceiver<Payload>> receivers;
}
and initialize an Instance for each type of IReceiver and then DI it into the IReceivers to enable them to register and get the Instances from other places.
Is this a good way to handle different Services? I think it gets kind of messy with many Brokers and I would rather have something like
static void register<Payload>(IReceiver<Payload> RegisterMe)
and
static List<IReceiver<Payload>> getReceivers<PayLoad>()
But im not able to implement this Locator because I dont know how to administrate different generic Lists in one non generic class
Any Suggestions?
Using a Dependency Injection framework you should be able to configure which receivers you want to particulary inject into specific Broker<PayLoad> instances.
In the other hand, you should practice constructor injection:
public class Broker<Payload>
{
public Broker(IList<IReceiver<PayLoad>> receivers)
{
Receivers = receivers;
}
public IList<IReceiver<PayLoad>> { get; }
}
Now, the next issue is that you want a broker to handle more than a receiver type. So the easiest way will be a small refactor on your IReceiver<PayLoad> interface:
// No more PayLoad generic type parameter! Let's move it to
// the methods
public interface IReceiver
{
string Name { get; }
Task SendObjectContainerAsync<TPayLoad>(ObjectContainer<TPayLoad> m);
Task<ObjectContainer<TPayLoad>> GetSnapshot<TPayLoad>();
}
Finally, your brokers will look as follows:
public class Broker
{
public Broker(IList<IReceiver> receivers)
{
Receivers = receivers;
}
public IList<IReceiver> { get; }
}
About the Locator thing
Are you going to implement a static service locator? Don't do this, it's considered an anti-pattern, because you're going to couple your components to how they receive their dependencies while you should avoid this.
Components should remain agnostic on how they get their dependencies, because this is a reponsibility of a higher layer, usually the IoC/DI container.
Also, it makes your code more test-friendly, because you can test your components without integrating the IoC/DI container, because you just expect constructor arguments.

Using Dependency Injection (Autofac) and avoiding Service Locator pattern

I'm taking a stab at properly implementing DI in my Xamarin Android application using Autofac but I'm having issues understanding how I should handle instantiating objects that require data passed into their constructor. For example one of our viewmodels needs a string and a guid passed in to its constructor. Something that looks promising is Delegate Functions offered by Autofac. This is where the line between Service Locator and DI appears to blur, at least in my mind. In order to use the Delegate Functions you must call container.Resolve, or rather it's recommended to use the IComponentContext.Resolve. Many blogs recommend not using Resolve outside of the bootstapper/main entry point. Is there something I am missing here? Is there a better way to create objects using DI? I am familiar with the Factory pattern to create objects but I feel that I'm losing the benefits of DI going that route since I am back to manually passing in services/objects to the newly created object. Thanks for any feedback!
It is not recommended to call container.Resolve() to use a delegate factory. The correct way is shown on the delegate factories page that you already linked to:
public class Portfolio
{
Shareholding.Factory ShareholdingFactory { get; set; }
IList<Shareholding> _holdings = new List<Shareholding>();
public Portfolio(Shareholding.Factory shareholdingFactory)
{
ShareholdingFactory = shareholdingFactory;
}
public void Add(string symbol, uint holding)
{
_holdings.Add(ShareholdingFactory(symbol, holding));
}
}
When the docs show an explicit call to container.Resolve() you should realize that they are not showing best practice, they are simply proving that it can be resolved without coding up a whole new class (like Portfolio) to consume it.
In order to use the Delegate Functions you must call container.Resolve
No, at least not in this case.
Assuming you have registered Shareholding. Now you can ask a dependency on Func<Shareholding>, ie. something hat returns a Shareholding when you call it.
But as the Shareholding constructor has two parameters, it cannot be resolved without supplying those parameters. Just add them to the declaration like this: Func<string, uint, Shareholding>. Now you can resolve the dependency when you supply those parameters.
Here is a better example.
I recently (yesterday) faced the same problem I wound up using the ServiceClient object you see in the code below. This object addresses your question about using the container outside of the bootstrapper. I have read arguments that say not to pass the container around and I think they are mostly valid. In my case however the ServiceClient class represents a single point of entry into my service layer so I thought it was appropriate to pass the container.
The way I use this at the moment is to pass an instance of ServiceClient into my BaseController:
// In Global.asax.cs
builder.RegisterControllers(typeof(MvcApplication).Assembly);
builder.RegisterType<ServiceClient>().As<IServiceClient>();
BaseController:
public abstract class BaseController<T> : Controller where T :class
{
public IServiceClient ServiceClient { get; set; }
public BaseController(IServiceClient serviceClient)
{
ServiceClient = serviceClient;
}
}
In my controller I can resolve, instantiate, and call a service that uses unmanaged resources with just one line like this:
myViewModel = await ServiceClient.OfType<ICustomerService>().TryAsync(x => x.GetCustomerByID(id));
ServiceClient:
public class ServiceClient : IServiceClient
{
private IComponentContext _container;
public ServiceClient(IComponentContext container)
{
_container = container;
}
public ServiceCallWrapper<T> OfType<T>() where T : class, IDisposable
{
return new ServiceCallWrapper<T>(_container);
}
}
public class ServiceCallWrapper<T> : IServiceCallWrapper<T> where T : class, IDisposable
{
private IComponentContext _container;
internal ServiceCallWrapper(IComponentContext container)
{
_container = container;
}
public void Try(Action<T> method)
{
// consider try/catch/log/throw here
using (T client = _container.Resolve<T>())
{
method(client);
}
}
public TResult Try<TResult>(Func<T, TResult> method)
{
using (T client = _container.Resolve<T>())
{
return method(client);
}
}
public async Task TryAsync(Func<T, Task> method)
{
using (T client = _container.Resolve<T>())
{
await method(client);
}
}
public async Task<TResult> TryAsync<TResult>(Func<T, Task<TResult>> method)
{
using (T client = _container.Resolve<T>())
{
return await method(client);
}
}
}

Isolating a dependency for an instance (and that instances dependencies) when instance created through a Factory

EDIT: I've cleaned this question up significantly after solving my problem, including changing the title.
I have a MessageChannel interface which defines (unsurprisingly) a channel that my classes can use to push messages to the end user.
Normally this MessageChannel is a Singleton and is bound to a ViewModel that implements the MessageChannel interface. Essentially, there is a single location at the top of my application where messages to the user will be shown. So far its worked pretty well.
This MessageChannel is used in a lot of places, one of which is in some operation classes that I have setup.
I now have a need for a LOCAL MessageChannel, such messages being posted in some reduced scope get posted to that local MessageChannel and not the global one.
What this means is that I need to be able to create instances of a ViewModel (through a Factory), such that that particular instance has its own MessageChannel instance AND that MessageChannel instance is shared for all dependencies injected into that ViewModel (and their dependencies and so on).
Some classes to illustrate. I have simplified things somewhat, my messages are more than just strings:
using Ninject;
using Ninject.Extensions.Factory;
public interface MessageChannel
{
void PostMessage(string message);
}
public class MessageChannelViewModel : MessageChannel
{
public string Message { get; set; }
public void PostMessage(string message)
{
Message = message;
}
}
public interface Operation
{
void Do();
}
public interface OperationFactory
{
Operation Create();
}
public class DefaultOperation : Operation
{
public DefaultOperation(MessageChannel userMessages)
{
_UserMessages = userMessages;
}
private readonly MessageChannel _UserMessages;
public void Do()
{
// Do something.
_UserMessages.PostMessage("Success!");
}
}
public interface IsolatedViewModel
{
MessageChannelViewModel LocalMessages { get; }
}
public interface IsolatedViewModelFactory
{
IsolatedViewModel Create();
}
public class DefaultIsolatedViewModel : IsolatedViewModel
{
public IsolatedViewModel(MessageChannelViewModel localMessages, OperationFactory opFactory)
{
_OpFactory = opFactory;
LocalMessages = localMessages;
}
private readonly OperationFactory _OpFactory;
public MessageChannelViewModel LocalMessages { get; private set; }
}
public class Module : NinjectModule
{
public override void Load()
{
Bind<MessageChannel, MessageChannelViewModel>().To<MessageChannelViewModel>().InSingletonScope();
Bind<Operation>().To<DefaultOperation>();
Bind<OperationFactory>().ToFactory();
Bind<IsolatedViewModel>().To<DefaultIsolatedViewModel>();
Bind<IsolatedViewModelFactory>().ToFactory();
// Something to make it so the IsolatedViewModel DOESNT get the Singleton
// instance of the MessageChannelViewModel, and instead gets once of its own
// AND so the Operations created by the OperationFactory injected into the
// IsolatedViewModel get the SAME MessageChannel, so messages being posted
// from any place in the IsolatedViewModel's dependencies are shown only\
// locally.
}
}
I tried the NamedScope extension but I couldn't get it do what I wanted it to do.
I think you can try to use The Ninject Context Preservation Extension which adds support for recording (and making available to Contextual Binding rules) the context pertaining to factories that call the Kernel to Resolve Requests.
This enables you to add contextual conditions to your Bindings.
I ended up using a combination of Ninject.Extensions.ContextPreservation and Ninject.Extensions.NamedScope to accomplish what I wanted.
The completed example module looks like this:
public class Module : NinjectModule
{
public override void Load()
{
Bind<MessageChannel, MessageChannelViewModel>().To<MessageChannelViewModel>().InSingletonScope();
Bind<Operation>().To<DefaultOperation>();
Bind<OperationFactory>().ToFactory();
var uniqueName = "UNIQUE";
Bind<IsolatedViewModel>()
.To<DefaultIsolatedViewModel>()
.Named(uniqueName)
.DefinesNamedScope(uniqueName);
Bind<MessageChannel, MessageChannelViewModel>().To<MessageChannelViewModel>()
.WhenAnyAncestorNamed(uniqueName)
.InNamedScope(uniqueName);
Bind<IsolatedViewModelFactory>().ToFactory();
}
}
Theres two parts to it.
You need the ContextPreservation extension to choose the correct binding based on the context available at the time that you resolve the object instance. In this case I used a name as context, meaning that my special MessageChannel binding will be used when resolving the MessageChannel dependency for any dependencies required under the IsolatedViewModel.
I needed the NamedScope extension to ensure that only 1 instance of the MessageChannel was created under each IsolatedViewModel instance (i.e. the instance was shared for that IsolatedViewModel and all its dependencies).
Some other things to be aware of:
If you are using any ToMethod bindings and you use the Kernel inside the method, you'll need to make sure you use a ContextPreservingGet or you'll lose your context and the correct binding wont be selected.
You'll have to look very closely at your bindings and double check any Singleton bindings because if any of the dependencies of your isolated class are bound in Singleton scope, and they have dependencies on the MessageChannel (for example) its not going to work like you want it to. I had to remove a couple of Singleton scoped bindings as a result of this (for the better probably).

Two services dependend on eachother (stackoverflow exception) - how to solve?

I am new to dependency injection, and I am trying to solve an issue. I have two services. Each of these services have methods who need eachother.
For instance: SiteManager have methods where it needs my ForumManager. My ForumManager have methods where it needs my SiteManager.
I have the following two classes:
public class SiteManager:ISiteManager
{
public IForumManager ForumManager { get; set; }
public SiteManager()
{
this.ForumManager = new ForumManager();
}
}
public class ForumManager:IForumManager
{
public ISiteManager SiteManager { get; set; }
public ForumManager()
{
this.SiteManager = new SiteManager();
}
}
Very obviously this will result in a stack overflow exception, as they call eachother. I've read a lot of posts here, and I think I just need a small hint on how to solve this. I have my interfaces in their own assembly.
I thought about putting the dependencies in their own property so when they are used, they are made. However, is this best practice?
I do not use an IoC container (and I haven't used that before).
Any hints on how to solve this particular issue in a "best practice" way! :-)
You should not be calling new within your classes, that will tightly couple them. The correct pattern for IOC that will allow you to test each class separately using mocks is:-
public class SiteManager:ISiteManager
{
private readonly IForumManager forumManager;
public SiteManager(IForumManager forumManager)
{
this.forumManager = forumManager;
}
}
public class ForumManager:IForumManager
{
private readonly ISiteManager siteManager;
public ForumManager(ISiteManager siteManager)
{
this.siteManager = siteManager;
}
}
But, that doesn't solve the mutual recursion. The easiest way to solve that is to not use constructor injection for one of the classes, but use property injection instead, i.e. put the SiteManager back to a public property on the ForumManager and set it after creating both objects.
Your setup code then does:-
IForumManager forumManager = new ForumManager();
ISiteManager siteManager = new SiteManager(forumManager);
forumManager.SiteManager = siteManager;
Another alternative would be to pass a ForumManagerFactory into the SiteManager, e.g. a Func<ISiteManager,IForumManager>.
ISiteManager siteManager = new SiteManager((s) => new ForumManager(s));
Inside the site manager you can then call the Func, passing this to get the IForumManager. The ForumManager gets an instance of the SiteManager and the SiteManager has the ForumManager object.
When using MVP with winforms and AutoFac, I had this exact same issue with the view referencing the presenter and the presenter referencing the view. The way I got around it is to have one of your classes pass itself to the other using an Initialize method. I am not sure if this is best practice, but I have seen it suggested before (this question about mvp)
So for the implementation details:
public class SiteManager:ISiteManager
{
public IForumManager ForumManager { get; set; }
public SiteManager()
{
}
public Initialize(IForumManager forumManager)
{
ForumManager = forumManager
}
}
public class ForumManager:IForumManager
{
public ISiteManager SiteManager { get; set; }
public ForumManager(ISiteManager siteManager)
{
this.SiteManager = new SiteManager();
this.SiteManager.Initialize(this);
}
}
Edit Actually would probably go with the other solutions posted, I was just looking at this purely from a circular dependency point of view
what you are doing and what you are suggesting both will cause stack overflow exception. i don't know why will you want to do something like that and you are not giving any hints on that but i guess i can offer you to create a manager, maybe a singleton, maybe just with static method and do:
public static void DoStuff(ISiteManager sm, IForumManager fm)
{
// your code here can use the best of both without SO
}
and not holding ISiteManager in ForumManager and IForumManager in SiteManager
You clearly can't have interdependant classes. What you need to do is to create a separate class and move there the methods which use the same time forum manager and sitemanger: Here is a sample 3rd class:
class ForumAndSiteManager
{
public ForumAndSiteManager(ISiteManager siteMaanger, IForumManager forumManager)
{
//save the injected object to private fileds
}
//define methods which will use both sitemanager and forum manager
}
This way you will brake the circular depedency
You should definitely avoid circular dependencies. I mean A depends on B and B on A.
This is like a cancer of your context dependencies. We used spring.net framework which contrary to java's version is unable to switch on a failing system if it discovers this kind of dependency. I have to say that this brings us only mess and hours of spring's logs searching and analyzing.
We defined almost 200 without any problem but once we added just another bean along with Lazy reference it failed down. This is almost impossible to untangle our solution to avoid it right now so we hook and hook and hook whilst it fails :-(

Interface design using C# Generics

I am currently designing a class library that will provide data to a web application graph rendering engine in C#. I am currently defining the interfaces of this library.
I have a IGraphData interface which I would like to cache using a service that accesses the cache, this is called IGraphDataCacheService and has set and get methods to add and retrieve IGraphData objects to and from the cache. the cache service will be a singleton.
I am confused about the correct way to implement this, so that there is only one cache service that can get and set generic IgraphData objects.
I came up with this:
interface IGraphDataCacheService {
IGraphData<object> Get(string identifier);
void Set(IGraphData<object> graphData);}
or this:
T Get<T, P>(string identifier) where T : IGraphData<P>;
void Set<T,P>(T graphData) where T : IGraphData<P>;
Can any one offer any advice help?
Thanks
Why don't you just make the interface generic instead?
interface ICacheService<T> {
T Get(string identifier);
void Set(T graphData);
}
if you wanted, you could type-constrain T to be of type IGraphData, or you could write it as:
interface IGraphDataCacheService<T> {
IGraphData<T> Get(string identifier);
void Set(IGraphData<T> graphData);
}
A few points:
I'd probably rename the interface methods to be more emblematic of a caching service. For example, Fetch and Store instead of Get and Set, which makes it sound like you're getting or setting the provider rather than the data to be cached.
Ensuring that there is only one cache is an implementation detail, not an interface one.
To implement a singleton, try something like:
public class SingletonCacheService : IGraphDataCacheService {
private static Singleton instance;
private Singleton() {}
// snip implementation of IGraphDataCacheService methods ...
public static Singleton Instance {
get {
if (instance == null) {
instance = new Singleton();
}
return instance;
}
}
}
Note that this simple version isn't threadsafe.
Both alternatives seem plausible at a glance; my hunch is that you need to write some 'typical' client code to decide. e.g. Does the typical client 'know' the type of data associated with the identifier it's looking up? Good API design requires identifying the main use scenarios and using that to inform the design.
If I understand your question correctly you are wanting to treat the generic types like they are the same, but in current .NET implementation you can't do this.
IGraphData<string> can't be passed as a IGraphData<object> they are actually different types even though string is an object, the generic types are not related and can't be cast or passed like they are the same.
If you control the IGraphData interface you can create a IGraphData interface and derive IGraphData from it and use IGraphData to access the cache. It just depends on how you are using it and what you have the control over.
You can do what you want in C# 4.0. There is an article about it here
You can't ensure there's only a single instance implementing an interface. However, you can make a class (e.g. GraphDataCacheServiceImpl) implementing the interface a singleton by sealing it and providing only a getter property, with the object created as a static variable from a private constructor. See the below. As far as generics, it's not exactly clear what you're seeking to accomplish. But I would guess the below is close to what you want.
interface IGraphDataCacheService<T> {
IGraphData<T> Get(string identifier);
void Set(IGraphData<T> graphData);
}
public sealed class GraphDataCacheServiceImpl<T> : IGraphDataCacheService<T>
{
private GraphDataCacheServiceImpl()
{
// ..
}
static GraphDataCacheServiceImpl()
{
Instance = new GraphDataCacheServiceImpl<T>();
}
public IGraphData<T> Get(string id)
{
return new GraphDataImpl<T>();
}
public void Set(IGraphData<T> graphData)
{
}
public static GraphDataCacheServiceImpl<T> Instance {get; private set;}
}

Categories

Resources