How should container behave when it is disposed? - c#-4.0

Should it throw an exception, pass resolution to its parent or something else?
My favorite container Autofac raises an exception - which is the only thing I don't like about it.
I think that it should pass resolution to its parent which should resolve my issue with this code
class LazyClass
{
public void DoSomething() { }
}
class SomeClass
{
public event EventHandler WatchOut = (s, ea) => { };
public void Start()
{
WatchOut(this, EventArgs.Empty);
}
}
class LazyInterceptor
{
Lazy<LazyClass> lazy;
public LazyInterceptor(Lazy<LazyClass> lazy)
{
this.lazy = lazy;
}
public void Register(SomeClass some)
{
some.WatchOut += (s, ea) => lazy.Value.DoSomething();
}
}
[TestMethod]
public void LazyAndEvents()
{
var builder = new ContainerBuilder();
builder.RegisterType<LazyClass>().SingleInstance();
var container = builder.Build();
var someClass = new SomeClass();
using (var inner = container.BeginLifetimeScope(cb =>
cb.RegisterType().SingleInstance()))
{
var interceptor = inner.Resolve();
interceptor.Register(someClass);
}
someClass.Start();
}
I know of three workarounds around this, but they all seem just wrong
not disposing container - this is what I currently do, but that's just to make Autofac happy
explicitly registering lazy - seems just wrong and I don't even know what will be resolved
taking ownership for dispose - it doesn't seem as bad, but I don't use object in that way, so again it looks like a workaround. Also, in Autofac it introduces dependency which is not nice

The whole point of lifetime scopes is that to control the lifetime of the contained instances. Building on the Disposable pattern, disposing the container is a clean and well-established way of releasing the resources governed by that container. Thus, when a lifetime scope is disposed you should no longer depend on instances resolved from that lifetime scope.
So I would say that you are definitively using Autofac the wrong way here. Perhaps if you explained why you want to use the scope like that, we could figure out the proper usage.

Related

ServiceStack.Funq.Quartz cannot instantiating type?

ServiceStack.Funq.Quartz Sample Code is
public class MyServices : Service
{
public object Any(Hello request)
{
return new HelloResponse { Result = "Hello, {0}!".Fmt(request.Name) };
}
}
public class HelloJob : IJob
{
private MyServices MyServices { get; set; }
public HelloJob(MyServices myServices)
{
MyServices = myServices;
}
public void Execute(IJobExecutionContext context)
{
var response = MyServices.Any(new ServiceModel.Hello
{
Name = "CodeRevver"
});
response.PrintDump();
}
}
The above is works fine. if I in the MyServices Class, removed the Any function, and comment the Execute inner code.
public class MyServices : Service
{
}
the quartz.net will get the error:
[Quartz.Core.ErrorLogger】 An error occurred instantiating job to be executed. job= 'JobGroup1.GetUserJob111' Problem instantiating type 'ServiceStackWithQuartz.HelloJob'
why the class must have public object Any(Hello request) function ?
Thanks for using the package – I had no idea that other people would find it useful.
So If I understand correctly, in your situation you have:
public class MyServices : Service
{
}
And you’re trying to resolve this Service via constructor injection, which is effectively doing a:
container.Resolve<MyServices>();
This will fail because of the way the ServiceStack Funq IoC works. You can’t resolve a ServiceStack Service that has nothing in it (you'd probably never want to either) – It has to at least have one service implementation, It doesn’t matter what the implementation is.
Also, if you want to improve ServiceStack.Funq.Quartz, feel free to contribute to the code base.
Edit: It's probably worth mentioning that you can inject a "Non-Service" class with your logic in it if you want. You can resolve other classes that aren't based off of ServiceStack.Service even if there's nothing in them.
Edit 2: Responding to your "Service wont dispose" problem. This is the same across ServiceStack and has nothing to do with your Quartz Job. If you call a:
container.Resolve<MyServices>().Any(new new ServiceModel.Hello { });
from AppHost for example, your service wont dispose by itself. If you want it to dispose you can wrap it in a using statement. e.g.
using (var service = MyServices)
{
var response = MyServices.Any(new ServiceModel.Hello { });
}
The using will ensure that your service will be disposed afterwards.
Alternatively you can add the interface "IDispose" on to your Quartz Job and implement a Dispose() method that will do a:
MyServices.Dispose();
This will be called after a job has executed.

Guice and RequestScoped behaviour in multiple threads

I am using Guice's RequestScoped and Provider in order to get instances of some classes during a user request. This works fine currently. Now I want to do some job in a background thread, using the same instances created during request.
However, when I call Provider.get(), guice returns an error:
Error in custom provider, com.google.inject.OutOfScopeException: Cannot
access scoped object. Either we are not currently inside an HTTP Servlet
request, or you may have forgotten to apply
com.google.inject.servlet.GuiceFilter as a servlet
filter for this request.
afaik, this is due to the fact that Guice uses thread local variables in order to keep track of the current request instances, so it is not possible to call Provider.get() from a thread different from the thread that is handling the request.
How can I get the same instances inside new threads using Provider? It is possible to achieve this writing a custom scope?
I recently solved this exact problem. There are a few things you can do. First, read up on ServletScopes.continueRequest(), which wraps a callable so it will execute as if it is within the current request. However, that's not a complete solution because it won't forward #RequestScoped objects, only basic things like the HttpServletResponse. That's because #RequestScoped objects are not expected to be thread safe. You have some options:
If your entire #RequestScoped hierarchy is computable from just the HTTP response, you're done! You will get new instances of these objects in the other thread though.
You can use the code snippet below to explicitly forward all RequestScoped objects, with the caveat that they will all be eagerly instantiated.
Some of my #RequestScoped objects couldn't handle being eagerly instantiated because they only work for certain requests. I extended the below solution with my own scope, #ThreadSafeRequestScoped, and only forwarded those ones.
Code sample:
public class RequestScopePropagator {
private final Map<Key<?>, Provider<?>> requestScopedValues = new HashMap<>();
#Inject
RequestScopePropagator(Injector injector) {
for (Map.Entry<Key<?>, Binding<?>> entry : injector.getAllBindings().entrySet()) {
Key<?> key = entry.getKey();
Binding<?> binding = entry.getValue();
// This is like Scopes.isSingleton() but we don't have to follow linked bindings
if (binding.acceptScopingVisitor(IS_REQUEST_SCOPED)) {
requestScopedValues.put(key, binding.getProvider());
}
}
}
private final BindingScopingVisitor<Boolean> IS_REQUEST_SCOPED = new BindingScopingVisitor<Boolean>() {
#Override
public Boolean visitScopeAnnotation(Class<? extends Annotation> scopeAnnotation) {
return scopeAnnotation == RequestScoped.class;
}
#Override
public Boolean visitScope(Scope scope) {
return scope == ServletScopes.REQUEST;
}
#Override
public Boolean visitNoScoping() {
return false;
}
#Override
public Boolean visitEagerSingleton() {
return false;
}
};
public <T> Callable<T> continueRequest(Callable<T> callable) {
Map<Key<?>, Object> seedMap = new HashMap<>();
for (Map.Entry<Key<?>, Provider<?>> entry : requestScopedValues.entrySet()) {
// This instantiates objects eagerly
seedMap.put(entry.getKey(), entry.getValue().get());
}
return ServletScopes.continueRequest(callable, seedMap);
}
}
I have faced the exact same problem but solved it in a different way. I use jOOQ in my projects and I have implemented transactions using a request scope object and an HTTP filter.
But then I created a background task which is spawned by the server in the middle of the night. And the injection is not working because there is no request scope.
Well. The solutions is simple: create a request scope manually. Of course there is no HTTP request going on but that's not the point (mostly). It is the concept of the request scope. So I just need a request scope that exists alongside my background task.
Guice has an easy way to create a request scope: ServletScope.scopeRequest.
public class MyBackgroundTask extends Thread {
#Override
public void run() {
RequestScoper scope = ServletScopes.scopeRequest(Collections.emptyMap());
try ( RequestScoper.CloseableScope ignored = scope.open() ) {
doTask();
}
}
private void doTask() {
}
}
Oh, and you probably will need some injections. Be sure to use providers there, you want to delay it's creation until inside the created scope.
Better use ServletScopes.transferRequest(Callable) in Guice 4

Confusion with IDisposable

I have some nagging doubts about the correct way to implement IDisposable. Consider the following scenario...
public class Foo : IDisposable {...}
public class Bar : IDisposable {
private bool disposed = false;
private readonly Foo MyFoo;
public Bar() {
this.MyFoo = new Foo();
}
public Bar(Foo foo) {
this.MyFoo = foo;
}
~Bar() {
Dispose(false);
}
protected virtual void Dispose(bool disposing) {
if (!this.disposed) {
if (disposing) {
if (MyFoo != null) {
this.MyFoo.Dispose();
this.MyFoo = null;
}
}
this.disposed = true;
}
}
public void Dispose() {
Dispose(true);
GC.SuppressFinalize(this);
}
}
My questions are:
1) If a class creates a disposable object, should it call the Dispose() method on that object in its own Dispose() method?
2) If a disposable object is passed to a class as a reference, should that class still call the Dispose() method on that reference object, or should it leave it to the class that created the object in the first place?
The above pattern seems to crop up quite a lot (particularly with DI), but I don't seem to be able to find a concrete example of the correct way to structure this.
Refer to Excellent MSDN article
Garbage Collection: Automatic Memory Management in the Microsoft .NET Framework
1) If a class creates a disposable object, should it call the Dispose() method on that object in its own Dispose() method?
Yes it should. Otherwise also, Dispose will be called. But that will increase life of object by atleast 1 generation. This is due to the finalizer in the class definition. Refer to the article link above.
2) If a disposable object is passed to a class as a reference, should that class still call the Dispose() method on that reference object, or should it leave it to the class that created the object in the first place?
It is responsibility of caller (more specifically the class which has created an instance) to call the Dispose method.
~Bar() {
Dispose(false);
}
Whenever you find yourself writing code like this, take a deep breath first and ask "do I actually need a finalizer?" It is extremely rare that you need one, a finalizer is only required when you take ownership of an unmanaged resource yourself.
The first litmus test is "does the finalizer actually do anything?" That's clear if you follow the code. It calls Dispose(false) and that code only does something when the argument is true. What follows is that you don't need a finalizer. This is entirely normal, finalizers is something that Microsoft worries about. They wrote the .NET framework classes that wrap an unmanaged resource. FileStream, Socket, etcetera. And above all, the SafeHandle classes, designed to wrap operating system handles. They have their own finalizer, you don't rewrite one yourself.
So without a finalizer, the code entirely collapses to the simple and correct implementation, you only need to call the Dispose() method of any disposable objects you store yourself:
public class Bar : IDisposable {
private readonly Foo MyFoo;
public Bar() {
this.MyFoo = new Foo();
}
public void Dispose() {
MyFoo.Dispose();
}
}

IDisposable + finalizer pattern

Looking at the IDisposable pattern + Finalizer pattern, there is something I don't understand:
public class ComplexCleanupBase : IDisposable
{
private bool disposed = false; // to detect redundant calls
public ComplexCleanupBase()
{
// allocate resources
}
protected virtual void Dispose(bool disposing)
{
if (!disposed)
{
if (disposing)
{
// dispose-only, i.e. non-finalizable logic
}
// shared cleanup logic
disposed = true;
}
}
~ComplexCleanupBase()
{
Dispose(false);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
}
From my understanding the pattern should be implemented like above.
1) Calling Dispose() fires GC.SuppressFinalize(this), which means that the object should not be put on the finalizer queue as its already properly disposed? That helps to free up the object faster?
2) But what if I am not calling Dispose() on this object at all? In that case the finalizer should kick in, correct? But Dispose(false); does absolutely nothing (only setting disposed = true). Is this intended? It feels like as if something is missing...
Question 1: Yes, if GC.SuppressFinalize is not called the object will be placed on the finalizer queue AND will move up a generation (if not already gen 2), which means that the memory for that object will not be reclaimed until the next pass of GC for the new generation.
Question 2: Your comment //shared cleanup logic is where the shared cleanup logic will go, this is where things other than setting disposed = true would happen.
Also, an aside: if your dispose logic should only be called once, consider acquiring a lock, an uncontested lock is very fast in .Net:
public class ComplexCleanupBase : IDisposable
{
private volatile bool disposed = false; // to detect redundant calls
private readonly object _mutex = new object();
protected virtual void Dispose(bool disposing)
{
if (!Monitor.TryEnter(_mutex))
{
// We're already being disposed.
return;
}
try
{
if (!disposed)
{
if (disposing)
{
// dispose-only, i.e. non-finalizable logic
}
// shared cleanup logic
disposed = true;
}
}
finally
{
Monitor.Exit(_mutex);
}
}
... other methods unchanged
}
If Dispose(false) isn't going to do anything, that's a very good indication that neither your class nor any class derived from it should include a C#-style "destructor" nor override Finalize, and the "disposing" argument should be regarded as a dummy whose purpose is to give the protected Dispose method a different signature from the public one.
Note that implementing a destructor or overriding Finalize in a derived class, when the parent class is not expecting such behavior, can produce Heisenbugs. Among other things, the GC can sometimes decide that a class object has been abandoned, triggering its finalizer/destructor, even while an entity referred to by a field of the class is being used. For example, suppose a static class usbThingie manipulates USB controllers using integer handles, and a wrapper class usbWrapper does something like:
UInt32 myHandle;
void sendData(Byte data[])
{
UsbThingie.send(myHandle, data[0], data.Length);
}
If a sendData() call is the last thing done to an instance of usbWrapper before it is abandoned, it would be possible for the garbage-collector to observe that once UsbThingie.send() is called--even before it returns--no further references will exist to the usbWrapper, and thus it can safely trigger the finalizer. If the finalizer tries to close the channel referred to by myHandle, that might disrupt the transmission that was taking place; if usbThingie isn't thread-safe, there's no telling what might happen.

Is there a way to new a class that's the same type as another class without directly specifying it

I have extension method that does something like this
public static void DoStuff(this ObjectContext context)
{
using(var newContext = new MyEntitiesContext())
{
// do stuff
newContext.SaveChanges();
}
context.SaveChanges();
}
I was wondering if there a way to new a context of the same type as the context passed in instead of specifying MyEntitiesContext?
Thanks in advance
If you don't mind reflection:
var context = Activator.CreateInstance(context.GetType());
Now you either need a base Type or - if you still don't mind reflection - you can simply call the method by name. Or, since you are using C#4 you could go with dynamic.
Edit: You could also Go this way:
public static void DoStuff<T>(this T context) where T : ObjectContext, new()
{
using(var newContext = new T())
{
// do stuff
newContext.SaveChanges();
}
context.SaveChanges();
}

Resources