WCF Service hosted by IIS 7 and global variables ( singletons ) - iis

In my case I am using Lucene.Net for search and would like to use single instances of IndexReader and IndexSearcher. Where should I move them from a method to be able just to instantiate once for the first query and then reuse.
public static List<MyType> GetIndexMatches(string fullTextIndexPath, string keyWord )
{
IndexSearcher searcher = null;
IndexReader reader = null;
try
{
searcher = new IndexSearcher(fullTextIndexPath);
reader = IndexReader.Open(fullTextIndexPath);
...

Have you tried making them static that exists at the Service level (not at the web method level)?

I am not sure if you are familiar with IoC (Inversion of Control), but if you use a container like Castle Windsor or Ninject 2 (both of these integrate well with WCF, and can take over the creation of WCF service instances through the container), you can configure some injectable dependencies for your IndexSearcher and IndexReader. When defining such a component, you can give them a "lifestyle" of singleton. The benefit of using an IoC container is that you can inject the same component instances into any dependent class that needs them, and easily reuse your singleton components across an entire application with ease.
Castle Windsor
Ninject 2

Related

Create AutoMapper in Test Project (including AutoMapper.Profile classes)

I have a .net core service api which uses AutoMapper, and in Startup::ConfigureServices the services collection uses the AddAutoMapper extension to perform all the initialization necessary for dependency injection of an IMapper interface, e.g. services.AddAutoMapper(typeof(Startup)); The way I understand it is that by doing this, scanning is done for any/all AutoMapper.Profile types in order to set up the IMapper for DI into other constructors. Works great.
Now I'm writing tests for the service, and am wondering how to create this IMapper outside of Startup? Mocking it seems pointless, I just want to use it, so how do I create an instance of what I need that utilizes all of the AutoMapper.Profiles I have set up?
I was able to get this working by simply creating a MapperConfiguration which points to the needed Profile classes:
var mapperConfig = new MapperConfiguration(cfg => cfg.AddProfile<TestProfile>());
IMapper _mapper = new Mapper(mapperConfig);

Does ServiceStack's default IoC have something similar to ninject's .ToFactory() Method?

Using ninject, I'm able to create an abstract factory using the following syntax from the application's composition root:
kernel.Bind<IBarFactory>().ToFactory();
Does ServiceStack's default IoC container similar functionality? I'd like to implement an abstract factory in one of my service classes in order to create repositories as needed.
One suggestion I've heard was to use:
HostContext.Container.Resolve<[InsertDependancyHere]>()
but I'd like to avoid creating access to the container outside of the composition root (the Apphost.cs file).
As far as i could tell, ServiceStack's Funq IoC implementation does not include this Abstract Factory implementation, like Ninject's Abstract Factory support (or Castle Windsor's Typed Factory Facility, which i used to use).
You can still avoid Service Locator anti-pattern by creating a concrete Factory implementation and injecting that to your classes.
public class BarFactory : IBarFactory
{
// constructor inject dependencies to the factory - no service locator
public BarFactory() { ... }
// create objects from factory
public IBar GetBar() { ... }
}
Your other classes can inject IBarFactory and call it directly.
Func is bare-bones by design, so will not have all the same features. ServiceStack added some features, but mostly having to do with autowiring registration.
If you can't create a concrete implementation for your factories, this other SO answer may show you how to do it yourself.

How to inject HttpRequestBase and HttpContextBase in Funq (while using ServiceStack)

I have been happily using AutoFaq for a couple of years and take advantage of its ability to easily inject HttpRequestBase and HttpContextBase in the MVC pipeline. This makes mocking and decoupling a lot easier.
I am in the process of changing my data layer to ServiceStack and as part of wiring the default Funq DI mechanism to my different layers I can't figure out how to inject HttpRequestBase and HttpContextBase.
Is there a way to do this? I am looking for the container.Register() analog inside of AppHost.Configure(Func.Container container).
Thanks
ServiceStack doesn't allow registering runtime dependencies with its IOC, although as ServiceStack Services and Request pipeline only binds to the IRequest interface which can just inject a mocked IRequest directly on the service when its required, e.g:
var service = new MyService {
Request = new MockHttpRequest()
};
var response = service.Get(new MyRequest { Id = 1 });
The Testing wiki shows other ways of testing ServiceStack services.
ServiceStack has it's own abstraction of the HttpContext and Request/Response. In v3.x, these are IRequestContext, IHttpRequest, IHttpResponse. This is to be implementation-independent of ASP.NET (console or Mono). It is recommended you use the abstractions instead of trying to use the underlying ASP.NET objects.
In your Service code, you may access them this way:
var httpReq = base.RequestContext.Get<IHttpRequest>();
var httpResp = base.RequestContext.Get<IHttpResponse>();
If you really need the real ASP.NET HttpContext, apparently you should be able to access it at IRequest.OriginalRequest. But if you are trying it the ServiceStack way, "don't do that".
More explanation of the Funq usage in v3 is here:
https://github.com/ServiceStackV3/ServiceStackV3/wiki/The-IoC-container

Servicestack - Grouping like services together

Was wondering if there's a recommended best-practice way of grouping similar services together in what's becoming a larger and larger project. Say that most of my services can be lumped in either dealing with "Pro" data or "Amateur" data (the data goes way beyond a simple flag in a table, the data itself is totally different, from different tables, on the pro or amateur side.
I know I can add routes to my classes...
/pro/service1
/am/service2
It looks like I can put the DTOs in namespaces....
What about the Service.Interface items (Service and Factory classes). Would you put those into namespaces also?
Finally, is there a way for the metadata page to reflect these groupings? I started to go down this road, but all the services listed out in alphabetical order, and you couldn't see the route or namespace differences between service1 and service2.
thank you
If you want, you can split multiple Service implementations across multiple dlls as described on the Modularizing Services wiki.
You can safely group service implementation classes into any nested folder groupings without having any impact to the external services. But changing the namespaces on DTO's can have an effect if your DTO's make use of object, interfaces or abstract classes which emit type info containing full namespaces.
In ServiceStack v4.09+ (now on MyGet) the MetadataFeature includes the ability to customize the ordering of the metadata page, e.g you can reverse the order of the metadata pages with:
var metadata = (MetadataFeature)Plugins.First(x => x is MetadataFeature);
metadata.IndexPageFilter = page => {
page.OperationNames.Sort((x,y) => y.CompareTo(x));
};
Organising your large project:
For a complex service(s) I setup 4 projects in one solution.
AppHost, This takes care of the configuration of the service. (References Model, Service and Types)
Model, This is the database model (Does not reference other projects)
Service, This is the implementation of the service only, not the interfaces or DTOs (References Model and Types)
Types, This includes my Interfaces, DTOs and routes. (Does not reference other projects)
Having a separate Types library allows the distribution to clients, for example for use with the ServiceStack JsonServiceClient.
Yes you can namespace the Interfaces, DTOs and factory classes, any way you want. They will work as long as they are referenced in your service correctly.
If you are trying to separate more than one service, you should consider separating your service code into logical folders within the Service project. i.e.
/Service/Pro
/Service/Amateur
Wrap the outer code of your Service methods in a public partial static class MyServiceStackApplication, with an appropriate name. Then reference this as the assembly in the AppHost constructor. So for example:
Pro Service (Service Project/Pro/UserActions.cs)
public partial static class MyServiceStackApplication
{
public partial class Pro
{
public class UserActionsService : Service
{
public User Get(GetUserRequest request)
{
}
}
// ...
}
}
Pro Service (Service Project/Pro/OtherActions.cs)
public partial static class MyServiceStackApplication
{
public partial class Pro
{
public class OtherActionsService : Service
{
public Other Get(GetOtherRequest request)
{
}
}
// ...
}
}
Amateur Service (Service Project/Am/UserActions.cs)
public partial static class MyServiceStackApplication
{
public partial class Amateur
{
public class UserActionsService : Service
{
public User Get(GetUserRequest request)
{
}
}
// ...
}
}
etc.
You can see from the above code we can have multiple files, all separated out and organised, but one assembly for ServiceStack to reference in the AppHost:
public AppHost() : base("Pro & Amateur Services", typeof(MyServiceStackApplication).Assembly) {}
Using the reference to the MyServiceStackApplication assembly, and using the partial keyword allows you to organise the code into manageable groupings.
Metadata:
Unfortunately separating the metadata by namespace isn't supported. You could try and customize the MetaDataFeature yourself, but it does seem like a useful feature, being able to separate multiple services where they are hosted in the one ServiceStack application. I would suggest you raise a feature request.
Mythz is bringing out features faster than lightning. :) Seems like he has that covered in the next release and you should be able to apply a custom filter to HostContext.Metadata.OperationNamesMap.

Can ACS Service Namespace creation be automated?

First, let me state my real problem: I've got code that makes calls to the ACS Management service, and I'd like my integration tests to be able to be run concurrently without each test run clobbering the others. That is, since multiple people / build servers might end up running these tests concurrently, if they're all using the same ACS service namespace, concurrency issues arise.
My thinking is the simplest means of achieving this would be to generate new, unique ACS service namespaces for each test runner -- but as far as I can tell, there's no automated way of creating new service namespaces (or management client keys). Am I wrong? Is there another way of going about this?
An automated method of creating new service namespaces would be extraordinarily helpful.
You are correct. That's not possible today. Maybe you can describe your scenario in more detail and there might be some alternative solutions to avoid having to recreate the namespace?
Technically it should be possible, since the Management Portal is a Silverlight application accessing a WCF RIA Service.
If you dig deep enough you'll find some useful information:
This is the Silverlight XAP for the management of Windows Azure AppFabric: https://appfabricportal.windows.azure.com/ClientBin/Microsoft.AppFabric.WebConsole.4.1.3.xap
This is the service being used when listing/creating/... namespaces etc..: https://appfabricportal.windows.azure.com/Services/Microsoft-AppFabric-Web-Services-AppFabricDomainService.svc?wsdl
And this is a piece of the DomainContext:
public sealed class AppFabricDomainContext : DomainContext
{
public AppFabricDomainContext(Uri serviceUri)
: this((DomainClient) new WebDomainClient<AppFabricDomainContext.IAppFabricDomainServiceContract>(serviceUri, true))
{
}
...
public InvokeOperation CreateServiceNamespace(IEnumerable<string> serviceNames, string parentProjectKey, string serviceNamespace, IEnumerable<string> packageKeys, string regionKey, Action<InvokeOperation> callback, object userState)
{
Dictionary<string, object> dictionary = new Dictionary<string, object>();
dictionary.Add("serviceNames", (object) serviceNames);
dictionary.Add("parentProjectKey", (object) parentProjectKey);
dictionary.Add("serviceNamespace", (object) serviceNamespace);
dictionary.Add("packageKeys", (object) packageKeys);
dictionary.Add("regionKey", (object) regionKey);
this.ValidateMethod("CreateServiceNamespace", (IDictionary<string, object>) dictionary);
return this.InvokeOperation("CreateServiceNamespace", typeof (void), (IDictionary<string, object>) dictionary, true, callback, userState);
}
}
Finding this info was the easy part, getting it to work... that's something else. Take the authentication part for example, you'll need to authenticate with Windows Live and use those credentials when calling the WCF RIA Service.
Good luck!

Resources