Castle Windsor WCF integration - DefaultServiceHostFactory, Kernel, etc - castle-windsor

I'm nearly done with a big NHibernate upgrade that ended up also being a Castle upgrade. I'm nearly there except the ASP.NET website won't run, because I'm getting an error where ServiceSecurityContext.Current is null. I could be wrong (I'm still new to Castle) but I think it has something to do with the change I made to registering the WCF facility.
Previously (in a class called ServiceLocator.cs) there was code like this:
/// <summary>
/// Register the WindsorServiceHostFactory with the container
/// </summary>
public static void RegisterWcfServer()
{
RegisterWcfFacility();
DefaultServiceHostFactory.RegisterContainer(Container.Kernel);
}
where the RegisterWcfFacility() method looked like this:
private static void RegisterWcfFacility()
{
IFacility[] facilities = Container.Kernel.GetFacilities();
bool hasWcfFacility = false;
foreach (IFacility facility in facilities)
{
if (facility.GetType() != typeof (WcfFacility))
continue;
hasWcfFacility = true;
break;
}
if (!hasWcfFacility)
Container.AddFacility<WcfFacility>();
}
Subsequently I've changed it to this (because I was trying to get it to compile obviously, and the DefaultServiceHostFactory no longer has a "RegisterContainer" method):
/// <summary>
/// Register the WindsorServiceHostFactory with the container
/// </summary>
public static void RegisterWcfServer()
{
RegisterWcfFacility();
// see: http://stackoverflow.com/questions/9729395/castlewindsor-3-0-and-defaultservicehostfactory-registercontainer
// obsolete:
//DefaultServiceHostFactory.RegisterContainer(Container.Kernel);
Container.Register(Component.For<DefaultServiceHostFactory>());
}
And my new version of "RegisterWcfFacility()" looks like this:
private static void RegisterWcfFacility()
{
var facilities = Container.Kernel.GetFacilities();
var hasWcfFacility = facilities.Any(facility => facility.GetType() == typeof (WcfFacility));
if (!hasWcfFacility)
Container.AddFacility<WcfFacility>();
}
I'm just posting this mainly to ask things like: am I completely barking up the wrong tree? Is the way I'm registering this facility legitimate? Could any of this explain why my ServiceSecurityContext.Current is null? (and yes I have seen this):
https://groups.google.com/forum/#!topic/castle-project-devel/VOQKW4XlvLM%5B1-25%5D
thanks for any advice. Cheers, -Dave

I just had the same problem and found the answer here. Turns out you just an initialise class in the folder App_Code that looks like this:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using Castle.Windsor;
using Castle.Facilities.WcfIntegration;
namespace YourNamespace
{
public static class InitialiseService
{
public static void AppInitialize()
{
var container = new WindsorContainer();
container.AddFacility<WcfFacility>();
}
}
}
Of course this relies on the WCF Castle Facility being installed from the package manager via:
install-package Castle.WcfIntegrationFacility
Hope this helps :)

Related

How to use DependencyResolver in Net48 selfhosted application?

I have gotten a task that contains creating a .Net 4.8 application that contains a "HttpSelfHostServer".
I'm stuck in the quest of assigning "IServiceCollection services" to config.DependencyResolver (of type System.Web.Http.Dependencies.IDependencyResolver)
I would really like not to use autofac or other frameworks, but all guids I can find are pointing toward these frameworks. Isn't Microsoft providing a way through?
I just had to solve the same issue. This is how i did it:
First I created a new facade class to map the IServiceCollection from the host builder to the interface HttpSelfHostConfiguration supports:
using System;
using System.Collections.Generic;
using System.Web.Http.Dependencies;
using Microsoft.Extensions.DependencyInjection;
namespace IntegrationReceiver.WebApi
{
public class HttpSelfHostDependencyResolver : IDependencyResolver
{
private readonly IServiceProvider sp;
private readonly IServiceScope scope;
public HttpSelfHostDependencyResolver(IServiceProvider sp)
{
this.sp = sp;
this.scope = null;
}
public HttpSelfHostDependencyResolver(IServiceScope scope)
{
this.sp = scope.ServiceProvider;
this.scope = scope;
}
public IDependencyScope BeginScope() => new HttpSelfHostDependencyResolver(sp.CreateScope());
public void Dispose() => scope?.Dispose();
public object GetService(Type serviceType) => sp.GetService(serviceType);
public IEnumerable<object> GetServices(Type serviceType) => sp.GetServices(serviceType);
}
}
This required me to get the latest NuGet package Microsoft.Extensions.DependencyInjection.Abstractions according to an answer here: How do I see all services that a .NET IServiceProvider can provide?
I then registered my HttpSelfHostServer in the service provider with this code:
services.AddSingleton(sp => new HttpSelfHostDependencyResolver(sp));
services.AddSingleton(sp =>
{
//Starting the HttpSelfHostServer with user-level permissions requires to first run a command like
// netsh http add urlacl url=http://+:8080/ user=[DOMAINNAME]\[USERNAME]
var config = new HttpSelfHostConfiguration("http://localhost:8080");
config.Routes.MapHttpRoute("API Default", "api/{controller}/{id}", new { id = RouteParameter.Optional });
config.DependencyResolver = sp.GetRequiredService<HttpSelfHostDependencyResolver>();
return new HttpSelfHostServer(config);
});
And finally, to find my ApiController, I had to register that too in the service provider. I did that simply with:
services.AddScoped<HealthCheckController>();
For brewity, I'm just including my api controller below to illustrate how it now gets its dependencies:
using System.Net.Http;
using System.Threading.Tasks;
using System.Web.Http;
namespace IntegrationReceiver.WebApi
{
public class HealthCheckController : ApiController
{
private readonly ServiceBusRunner serviceBusRunner;
public HealthCheckController(ServiceBusRunner serviceBusRunner)
{
this.serviceBusRunner = serviceBusRunner;
}
[HttpGet]
public async Task<HttpResponseMessage> Get()
{
var response = new
{
serviceBusRunner.RunningTasks,
serviceBusRunner.MaxRunningTasks
};
return await Json(response)
.ExecuteAsync(System.Threading.CancellationToken.None);
}
}
}
This is a pretty dumb-down implementation but works for me until I can upgrade this code to net5.
I hope it helps you too!

How can I pass a function as input for a class in Processing

I am making a framework for making fractals in processing, however, I need to use functions as parameters for a constructor of a class.
Something like:
class Fractal {
String name;
void initialize;
Fractal(String Name, void setup) {
...
}
}
I'm going to guess you're coming from a JavaScript background?
Traditionally, Java didn't really have a way to do this. Instead you'd pass an anonymous instance of an interface, like this:
interface Runner{
public void run();
}
class Fractal {
String name;
Runner initialize;
Fractal(String name, Runner setup) {
...
}
}
Runner r = new Runner(){
public void run(){
// whatever
}
}
Fractal fractal = new Fractal("name here", r);
Note that Java provides a Runnable interface that you can use instead of creating your own, but I wanted to spell it out here to make it more obvious.
As of Java 8, you can pass a reference to a function as a parameter. This is called a lambda function. Googling "Java lambda function" will return a ton of results.
From this answer:
public void pass() {
run(()-> System.out.println("Hello world"));
}
public void run(Runnable function) {
function.run();
}
Depending on how you're using Processing, you might be stuck with the first approach though, since I don't think the Processing editor supports Java 8 yet.

how can i deep clone a list<T> in windows phone 8.1 without icloneable interface?

I want to deep clone a generic list but icloneable interface is not present in windows phone 8.1 also binaryformatter class is also not present?
Try this
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
public static T DeepClone<T>(T obj)
{
using (var ms = new MemoryStream())
{
var formatter = new BinaryFormatter();
formatter.Serialize(ms, obj);
ms.Position = 0;
return (T) formatter.Deserialize(ms);
}
}
Your class MUST be marked as [Serializable] in order for this to work.
Your source file must include the following code:
If you want clone all members and then refer this Deep Copy of Object in C#
You can create your own icloneable interface and define a function as follows:
public interface IClonable<T>
{
T Clone();
}
public static T[] Clone<T>(this T[] origin) where T : IClonable<T>
{
return origin.Select(x => x.Clone()).ToArray();
}

Set default implementation in Castle Windsor 2.5 (for decorators)

I'm working with Castle Windsor 2.5 (upgrading is not currently an option), and am trying to register decorators after the original components have been registered. It seems that in castle version 3 you can use IsDefault to achieve this. Is there a similar operation in castle 2.5 or else some other way to achieve this?
Just to be clear, I cannot change the registration order so that decorators are registered first. This is a platform architecture in which the default platform behavior can be modified by customers by adding to or changing existing registrations.
Looks like IHandlerSelector does the trick:
public class DecoratorHandler : IHandlerSelector
{
private readonly IWindsorContainer _container;
private readonly HashSet<Type> _decoratedTypes = new HashSet<Type>();
public DecoratorHandler(IWindsorContainer container)
{
_container = container;
}
public bool HasOpinionAbout(string key, Type service)
{
return _decoratedTypes.Contains(service);
}
public IHandler SelectHandler(string key, Type service, IHandler[] handlers)
{
return handlers[handlers.Length - 1];
}
public void Register<TTarget, TDecorator>() where TDecorator : TTarget, IDecorator<TTarget>
{
_container.Register(Component.For<TTarget>().ImplementedBy<TDecorator>());
_decoratedTypes.Add(typeof(TTarget));
}
}
And
_decoratorHandler = new DecoratorHandler(_container);
_container.Kernel.AddHandlerSelector(_decoratorHandler);

What control do I have over the TypedFactory Windsor implements?

My colleague set up a Windsor TypedFactoryFacility in our project.
I'm new to Windsor and don't understand how it is implementing the the methods in the IServiceFactory interface we register as a factory. When I saw a Create method that takes a type parameter T and returns a T, I figured that it's probably calling the container's Resolve method under the covers.
I need an overload of Create that takes a Type as a parameter and returns an object. Since the container's Resolve method has both of these flavors:
T Resolve<T>(string key);
object Resolve(Type service);
I thought adding the overload of Create would work. Instead, it appears to be trying to resolve a System.Object instead of the Type I pass in.
Is there a way to make Windsor implement my Create method the way I want it to? I've poked around a bit with reflector, but can't figure it out.
Here is the registration:
container.AddFacility<TypedFactoryFacility>();
container.Register(
Component.For<IServiceFactory>()
.AsFactory()
.LifeStyle.Transient);
and the interface itself:
public interface IServiceFactory
{
//Original Create method that works
T Create<T>();
//The overload that I need that throws an exception
object Create(Type service)
void Release(object service);
}
Do you want to call something like serviceFactory.Create(typeof(IMyServce)) instead of serviceFactory.Create<IMyService>()?
Try using reflection in an extension method, like this
public static class ServiceFactoryExtensions
{
public static object Create(this IServiceFactory factory, Type serviceType)
{
return typeof(IServiceFactory).GetMethod("Create")
.MakeGenericMethod(serviceType).Invoke(factory, new object[]{});
}
}
EDIT:
This extension method does indeed work with a factory created by Castle Windsor.
Here's my original test code, which you can drop into Program.cs of a VS2010 console application, add a reference to Castle.Core and Castle.Windsor, and run. I used Castle.Windsor 2.5.4.
using System;
using Castle.Facilities.TypedFactory;
using Castle.MicroKernel.Registration;
using Castle.Windsor;
namespace StackOverflow9198461
{
public static class ServiceFactoryExtensions
{
public static object Create(this IServiceFactory factory, Type serviceType)
{
return typeof(IServiceFactory).GetMethod("Create")
.MakeGenericMethod(serviceType)
.Invoke(factory, new object[] { });
}
}
class Program
{
static void Main()
{
var container = new WindsorContainer();
container.AddFacility<TypedFactoryFacility>();
container.Register(Component
.For<IServiceFactory>()
.AsFactory());
container.Register(Component
.For<IMyService>()
.ImplementedBy<MyService>()
.LifeStyle.Singleton);
var factory = container.Resolve<IServiceFactory>();
var s1 = factory.Create<IMyService>();
var s2 = factory.Create(typeof(IMyService));
Console.WriteLine(s1.GetType().FullName);
Console.WriteLine(s2.GetType().FullName);
if (s1 == s2) Console.WriteLine("Success");
}
}
public interface IServiceFactory
{
//Original Create method that works
T Create<T>();
////The overload that I need that throws an exception
//object Create(Type service)
void Release(object service);
}
public class MyService : IMyService
{
}
public interface IMyService
{
}
}