I have a class that I want to test using XCTest, and this class looks something like this:
public class MyClass: NSObject {
func method() {
// Do something...
// ...
SingletonClass.sharedInstance.callMethod()
}
}
The class uses a singleton that is implemented as this:
public class SingletonClass: NSObject {
// Only accessible using singleton
static let sharedInstance = SingletonClass()
private override init() {
super.init()
}
func callMethod() {
// Do something crazy that shouldn't run under tests
}
}
Now for the test. I want to test that method() actually does what it is supposed to do, but I don't want to invoke the code in callMethod() (because it does some horrible async/network/thread stuff that shouldn't run under tests of MyClass, and will make the tests crash).
So what I basically would like to do is this:
SingletonClass = MockSingletonClass: SingletonClass {
override func callMethod() {
// Do nothing
}
let myObject = MyClass()
myObject.method()
// Check if tests passed
This obviously isn't valid Swift, but you get the idea. How can I override callMethod() just for this particular test, to make it harmless?
EDIT: I tried solving this using a form of dependency injection, but ran into big problems. I created a custom init-method just to be used for tests such that I could create my objects like this:
let myObject = MyClass(singleton: MockSingletonClass)
and let MyClass look like this
public class MyClass: NSObject {
let singleton: SingletonClass
init(mockSingleton: SingletonClass){
self.singleton = mockSingleton
}
init() {
singleton = SingletonClass.sharedInstance
}
func method() {
// Do something...
// ...
singleton.callMethod()
}
}
Mixing in test code with the rest of the code is something I find a bit unpleasing, but okay. The BIG problem was that I had two singletons constructed like this in my project, both referencing each other:
public class FirstSingletonClass: NSObject {
// Only accessible using singleton
static let sharedInstance = FirstSingletonClass()
let secondSingleton: SecondSingletonClass
init(mockSingleton: SecondSingletonClass){
self.secondSingleton = mockSingleton
}
private override init() {
secondSingleton = SecondSingletonClass.sharedInstance
super.init()
}
func someMethod(){
// Use secondSingleton
}
}
public class SecondSingletonClass: NSObject {
// Only accessible using singleton
static let sharedInstance = SecondSingletonClass()
let firstSingleton: FirstSingletonClass
init(mockSingleton: FirstSingletonClass){
self.firstSingleton = mockSingleton
}
private override init() {
firstSingleton = FirstSingletonClass.sharedInstance
super.init()
}
func someOtherMethod(){
// Use firstSingleton
}
}
This created a deadlock when one of the singletons where first used, as the init method would wait for the init method of the other, and so on...
Your singletons are following a very common pattern in Swift/Objective-C code bases. It is also, as you have seen, very difficult to test and an easy way to write untestable code. There are times when a singleton is a useful pattern but my experience has been that most uses of the pattern are actually a poor fit for the needs of the app.
The +shared_ style singleton from Objective-C and Swift class constant singletons usually provide two behaviors:
It might enforce that only a single instance of a class can be instantiated. (In practice this is often not enforced and you can continue to alloc/init additional instances and the app instead depends on developers following a convention of exclusively accessing a shared instance via the class method.)
It acts as a global, allowing access to a shared instance of a class.
Behavior #1 is occasionally useful while behavior #2 is just a global with a design pattern diploma.
I would resolve your conflict by removing the globals entirely. Inject your dependencies all of the time instead of just for testing and consider what responsibility that exposes in your app when you need something to coordinate whatever set of shared resources you're injecting.
A first pass at injecting dependencies throughout an app is often painful; "but I need this instance everywhere!". Use it as a prompt to reconsider the design, why are so many components accessing the same global state and how might it be modeled instead to provide better isolation?
There are cases where you want a single copy of some mutable shared state and a singleton instance is perhaps the best implementation. However I find that in most examples that still doesn't hold true. Developers are usually looking for shared state but with some conditions: there's only one screen until an external display is connected, there's only one user until they sign out and into a second account, there's only one network request queue until you find a need for authenticated vs anonymous requests. Similarly you often want a shared instance until the execution of the next test case.
Given how few "singleton"s seem to use failable initializers (or obj-c init methods which return an existing shared instance) it seems that developers are happy to share this state by convention so I see no reason not to inject the shared object and write readily testable classes instead of using globals.
I eventually solved this using the code
class SingletonClass: NSObject {
#if TEST
// Only used for tests
static var sharedInstance: SingletonClass!
// Public init
override init() {
super.init()
}
#else
// Only accessible using singleton
static let sharedInstance = SingletonClass()
private override init() {
super.init()
}
#endif
func callMethod() {
// Do something crazy that shouldn't run under tests
}
}
This way I can easily mock my class during tests:
private class MockSingleton : SingletonClass {
override callMethod() {}
}
In tests:
SingletonClass.sharedInstance = MockSingleton()
The test-only code is activated by adding -D TEST to "Other Swift Flags" in Build Settings for the app test target.
I had a similar issue in my app, and in my case it made sense to use Singletons for these particular services as they were proxies for external services that were also singletons.
I ended up implementing a Dependency Injection model using https://github.com/Swinject/Swinject. It took about a day to implement for about 6 classes which seems like a lot of time to enable this level of unit testability. It did make me think hard about the dependencies between my service classes, and it made me more explicitly indicate these in the class definitions. I used the ObjectScope in Swinject to indicate to the DI framework that they're singletons: https://github.com/Swinject/Swinject/blob/master/Documentation/ObjectScopes.md
I was able to have my singletons, and pass in mock versions of them to my unit tests.
Thoughts on this approach: it seems more error prone as I could forget to initialize my dependencies correctly (and would never receive a runtime error). Finally, it doesn't prevent someone from just instantiating a instance of my Service class directly (which was sort of the whole point of the singleton), since my init methods had to be made public for the DI Framework to instantiate the objects into the registry.
I would suggest to make init not private (quite not convenient), but don't see better solution for now that object can be tested, if you need to simulate multi calls of initializing of the data type.
Related
I'm trying out Cake (C# Make). So far all the examples and documentation have the script file declaring all of its code inside delegates, like this:
Task("Clean")
.Does(() =>
{
// Delete a file.
DeleteFile("./file.txt");
// Clean a directory.
CleanDirectory("./temp");
});
However, one of the reasons I'm interested in using Cake is the possibility of writing my build scripts in a similar way to how I write code, as the scripts use a C#-based DSL. Included in this possibility is the ability to separate code that I use into methods (or functions / subroutines, whatever terminology is appropriate) so I can separate concerns and reuse code. For example, I may want to run the same set of steps for a multiple SKUs.
While I realize that I could create my own separate DLL with Script Aliases, I would like to avoid having to recompile a separate project every time I want to change these bits of shared code when working on the build script. Is there a way to define, inline with the normal build.cake file, methods that can still run the Cake aliases (e.g., DeleteFile) and can themselves be called from my Cake tasks?
Cake is C#, so you can create classes, methods, just like in regular C#
I.e. declare a class in a cake file
public class MyClass
{
public void MyMethod()
{
}
public static void MyStaticMethod()
{
}
}
and then use it a script like
var myClass = new MyClass();
// Call instance method
myClass.MyMethod();
//Call static method
MyClass.MyStaticMethod();
The Cake DSL is based on Roslyn scripting so there are some differences, code is essentially already in a type so you can declare a method without a class for reuse
public void MyMethod()
{
}
and then it can be called like a global methods
MyMethod();
A few gotchas, doing class will change scoping so you won't have access to aliases / context and global methods. You can get around this by i.e. passing ICakeContext as a parameter to class
public class MyClass
{
ICakeContext Context { get; }
public MyClass(ICakeContext context)
{
Context = context;
}
public void MyMethod()
{
Context.Information("Hello");
}
}
then used like this
// pass reference to Cake context
var myClass = new MyClass(Context);
// Call instance method which uses an Cake alias.
myClass.MyMethod();
You can have extension methods, but these can't be in a class, example:
public static void MyMethod(this ICakeContext context, string message)
{
context.Information(message);
}
Context.MyMethod("Hello");
My goal is to write a class and have a function in it that contains code to run (in a run() function for example) in a background thread. Here are some requirements of my class (and related classes):
Ensure that when I write the run() function, the code is guaranteed to run in a background thread without the programmer needing to know anything about threading and without having to remember to call any other code in that run() function related to the threading.
Have a completion function function that is set elsewhere that is called when the background thread is finished its processing without the programmer having to write code in this run() function to make the call.
Pretty much let someone derive a class from some base class and then write their background code in it in a run() function without writing anything else related to managing the background thread, completion function, etc.
Here's the code I might write in C#, in two DIFFERENT files:
class MyBase
{
public Action completionFunction = NULL;
public void begin()
{
RunInOtherThread( run ); // This function call is just pseudo-code for running that run() function in a background thread.
if( completionFunction != Null )
completionFunction();
}
virtual protected void run() = 0 // so this class cannot be instantiated
{
}
};
And in the other file:
class MySpecificClass : MyBase
{
override void run()
{
// Do important stuff here!
}
};
I do not know how to meet my requirements in Swift. They left out the "protected" level of protection for reasons that do not make sense to me (like thinking that I could not just fire a programmer that screwed up the code by exposing a base class protected function through a public function).
I am not familiar enough with some of the features of Swift to get these results. I do not need to have the classes work like the C# code even though it is a pretty good solution for me and my C# programmers.
How can I meet my requirements Swift?
BTW, I have seen Q&A about this with no reasonable way to fake the protected access level. I don't need to fake it, I just need another way to achieve the goal of hiding code in a derived class from all the world except for the base class, or something like that.
I'd be tempted to use protocols for this, rather than sub-classing. For example:
public protocol MyBase {
// *** This requires any object that conforms to the protocol
// *** to provide these, without specifying what they do
var completionFunction: (() -> ())? {get set}
func run()
}
public extension MyBase {
// *** This extension provides all objects that conform to the
// *** protocol with this function
func begin() {
RunInOtherThread( self.run ) // This function call is just pseudo-code for running that run() function in a background thread.
if let c = self.completionFunction {
c()
}
}
}
public class MySpecificClass: MyBase {
// *** Now, rather than subclassing, we simply conform to the protocol
public var completionFunction: (() -> ())? = nil
public func run() {
// *** No need to `override` - but *must* be supplied
// Do important stuff here!
}
}
The idea is just simple and works in the other containers, not limited with .Net:
Singleton component being referenced from within request context references transient component which in turn references request-scoped component (some UnitOfWork).
I expected that Autofac would resolve the same scoped component in both cases:
- when I request it directly from request scope
- when I request it by invoking Func<>
Unfortunately the reality is quite a bit different - Autofac sticks SingleInstance component to the root scope and resolves InstancePerLifetimeScope component on
the root component introducing memory leak (!!!) as UnitOfWork is disposable and becomes tracked by root scope (attempt to use matching web request scope would just fail finding request scope which is yet more misleading).
Now I'm wondering whether such behavior is by design or just a bug? If it is by design I'm not sure what are the use cases and why it differs from the other containers.
The example is as follows (including working SimpleInjector case):
namespace AutofacTest
{
using System;
using System.Linq;
using System.Linq.Expressions;
using Autofac;
using NUnit.Framework;
using SimpleInjector;
using SimpleInjector.Lifestyles;
public class SingletonComponent
{
public Func<TransientComponent> Transient { get; }
public Func<ScopedComponent> Scoped { get; }
public SingletonComponent(Func<TransientComponent> transient, Func<ScopedComponent> scoped)
{
Transient = transient;
Scoped = scoped;
}
}
public class ScopedComponent : IDisposable
{
public void Dispose()
{
}
}
public class TransientComponent
{
public ScopedComponent Scoped { get; }
public TransientComponent(ScopedComponent scopedComponent)
{
this.Scoped = scopedComponent;
}
}
class Program
{
static void Main(string[] args)
{
try
{
AutofacTest();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
try
{
SimpleInjectorTest();
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private static void AutofacTest()
{
var builder = new ContainerBuilder();
builder.RegisterType<ScopedComponent>().InstancePerLifetimeScope();
builder.RegisterType<SingletonComponent>().SingleInstance();
builder.RegisterType<TransientComponent>();
var container = builder.Build();
var outerSingleton = container.Resolve<SingletonComponent>();
using (var scope = container.BeginLifetimeScope())
{
var singleton = scope.Resolve<SingletonComponent>();
Assert.That(outerSingleton, Is.SameAs(singleton));
var transient = scope.Resolve<TransientComponent>();
var scoped = scope.Resolve<ScopedComponent>();
Assert.That(singleton.Transient(), Is.Not.SameAs(transient));
// this fails
Assert.That(singleton.Transient().Scoped, Is.SameAs(scoped));
Assert.That(transient.Scoped, Is.SameAs(scoped));
Assert.That(singleton.Scoped(), Is.SameAs(scoped)); // this fails
Assert.That(singleton.Transient(), Is.Not.SameAs(transient));
}
}
private static void SimpleInjectorTest()
{
var container = new SimpleInjector.Container();
container.Options.AllowResolvingFuncFactories();
container.Options.DefaultScopedLifestyle = new AsyncScopedLifestyle();
container.Register<ScopedComponent>(Lifestyle.Scoped);
container.Register<SingletonComponent>(Lifestyle.Singleton);
container.Register<TransientComponent>(Lifestyle.Transient);
container.Verify();
var outerSingleton = container.GetInstance<SingletonComponent>();
using (var scope = AsyncScopedLifestyle.BeginScope(container))
{
var singleton = container.GetInstance<SingletonComponent>();
Assert.That(outerSingleton, Is.SameAs(singleton));
var transient = container.GetInstance<TransientComponent>();
var scoped = container.GetInstance<ScopedComponent>();
Assert.That(singleton.Transient(), Is.Not.SameAs(transient));
Assert.That(singleton.Transient().Scoped, Is.SameAs(scoped));
Assert.That(transient.Scoped, Is.SameAs(scoped));
Assert.That(singleton.Scoped(), Is.SameAs(scoped));
Assert.That(singleton.Transient(), Is.Not.SameAs(transient));
}
}
}
public static class SimpleInjectorExtensions
{
public static void AllowResolvingFuncFactories(this ContainerOptions options)
{
options.Container.ResolveUnregisteredType += (s, e) =>
{
var type = e.UnregisteredServiceType;
if (!type.IsGenericType || type.GetGenericTypeDefinition() != typeof(Func<>))
{
return;
}
Type serviceType = type.GetGenericArguments().First();
InstanceProducer registration = options.Container.GetRegistration(serviceType, true);
Type funcType = typeof(Func<>).MakeGenericType(serviceType);
var factoryDelegate = Expression.Lambda(funcType, registration.BuildExpression()).Compile();
e.Register(Expression.Constant(factoryDelegate));
};
}
}
}
The short version what you're seeing is not a bug, you're just misunderstanding some of the finer points of lifetime scopes and captive dependencies.
First, a couple of background references from the Autofac docs:
Controlling Scope and Lifetime explains a lot about how lifetime scopes and that hierarchy works.
Captive Dependencies talks about why you don't generally shouldn't take an instance-per-lifetime or instance-per-dependency scoped item into a singleton.
Disposal talks about how Autofac auto-disposes IDisposable items and how you can opt out of that.
Implicit Relationship Types describes the Owned<T> relationship type used as part of the IDisposable opt-out.
Some big key takeaways from these docs that directly affect your situation:
Autofac tracks IDisposable components so they can be automatically disposed along with the lifetime scope. That means it will hold references to any resolved IDisposable objects until the parent lifetime scope is resolved.
You can opt out of IDisposable tracking either by registering the component as ExternallyOwned or by using Owned<T> in the constructor parameter being injected. (Instead of taking in an IDependency take in an Owned<IDependency>.)
Singletons live in the root lifetime scope. That means any time you resolve a singleton it will be resolved from the root lifetime scope. If it is IDisposable it will be tracked in the root lifetime scope and not released until that root scope - the container itself - is disposed.
The Func<T> dependency relationship is tied to the same lifetime scope as the object in which it's injected. If you have a singleton, that means the Func<T> will resolve things from the same lifetime scope as the singleton - the root lifetime scope. If you have something that's instance-per-dependency, the Func<T> will be attached to whatever scope the owning component is in.
Knowing that, you can see why your singleton, which takes in a Func<T>, keeps trying to resolve these things from the root lifetime scope. You can also see why you're seeing a memory leak situation - you haven't opted out of the disposal tracking for the things that are being resolved by that Func<T>.
So the question is, how do you fix it?
Option 1: Redesign
Generally speaking, it would be better to invert the relationship between the singleton and the thing you have to resolve via Func<T>; or stop using a singleton altogether and let that be a smaller lifetime scope.
For example, say you have some IDatabase service that needs an IPerformTransaction to get things done. The database connection is expensive to spin up, so you might make that a singleton. You might then have something like this:
public class DatabaseThing : IDatabase
{
public DatabaseThing(Func<IPerformTransaction> factory) { ... }
public void DoWork()
{
var transaction = this.factory();
transaction.DoSomethingWithData(this.Data);
}
}
So, like, the thing that's expensive to spin up uses a Func<T> to generate the cheap thing on the fly and work with it.
Inverting that relationship would look like this:
public PerformsTransaction : IPerformTransaction
{
public PerformsTransaction(IDatabase database) { ... }
public void DoSomethingWithData()
{
this.DoSomething(this.Database.Data);
}
}
The idea is that you'd resolve the transaction thing and it'd take the singleton in as a dependency. The cheaper item could easily be disposed along with child lifetime scopes (i.e., per request) but the singleton would remain.
It'd be better to redesign if you can because even with the other options you'll have a rough time getting "instance per request" sorts of things into a singleton. (And that's a bad idea anyway from both a captive dependency and threading standpoint.)
Option 2: Abandon Singleton
If you can't redesign, a good second choice would be to make the lifetime of the singleton... not be a singleton. Let it be instance-per-scope or instance-per-dependency and stop using Func<T>. Let everything get resolved from a child lifetime scope and be disposed when the scope is disposed.
I recognize that's not always possible for a variety of reasons. But if it is possible, that's another way to escape the problem.
Option 3: Use ExternallyOwned
If you can't redesign, you could register the disposable items consumed by the singleton as ExternallyOwned.
builder.RegisterType<ThingConsumedBySingleton>()
.As<IConsumedBySingleton>()
.ExternallyOwned();
Doing that will tell Autofac to not track the disposable. You won't have the memory leak. You will be responsible for disposing the resolved objects yourself. You will also still be getting them from the root lifetime scope since the singleton is getting a Func<T> injected.
public void MethodInsideSingleton()
{
using(var thing = this.ThingFactory())
{
// Do the work you need to and dispose of the
// resolved item yourself when done.
}
}
Option 4: Owned<T>
If you don't want to always manually dispose of the service you're consuming - you only want to deal with that inside the singleton - you could register it as normal but consume a Func<Owned<T>>. Then the singleton will resolve things as expected but the container won't track it for disposal.
public void MethodInsideSingleton()
{
using(var ownedThing = this.ThingFactory())
{
var thing = ownedThing.Value;
// Do the work you need to and dispose of the
// resolved item yourself when done.
}
}
This question is probably going to illustrate a lack of knowledge on my part about how Groovy classes work, but I have tried to figure this out on my own with no luck. I want to create a getProperty() method on a class so I can reference member variables in a Groovyish way. This is NOT the same as just making them public because I do want some logic done when they are referenced. Basically, I'm trying to create a configuration Groovy class that uses ConfigSlurper:
class Configuration implements GroovyObject {
private static ConfigObject config = new ConfigSlurper().parse(new File("testing.conf").toURI().toURL())
//This method is illegal, but it illustrates what I want to do
public static String getProperty(String prop){
config.getProperty(prop)
}
}
If the above class were legal, I could then reference config items like so:
Configuration.dbUser
instead of this, which would require making the ConfigObject available:
Configuration.config.dbUser
I know, it would be worlds easier to just make the config object public, but knowing how to do this (or know why it's impossible) would help me understand Groovy a little better.
The only way I can get it to work is via the metaClass:
class Configuration {
private static ConfigObject config = new ConfigSlurper().parse( "foo = 'bar'" )
}
Configuration.metaClass.static.propertyMissing = { name ->
delegate.config[ name ]
}
println Configuration.foo
There may be a better way however...
newbie here, sorry if this is an obvious question.
I've read from this page: http://code.google.com/p/autofac/wiki/NewInV2
In Autofac 1, weak references are held by the container. This makes sense if the objects being referenced use disposal to release GC/finalizer resources, but if the dispose method contains application logic then GC timing could introduce unexpected behaviour.
Autofac 2 holds normal references. To opt out of this behaviour and mange disposal manually, use the ExternallyOwned registration modifier.
Is that mean when I need to release an object that is resolved by Autofac to the GC, I cannot simply say:
a = null;
because Autofac holds a strong reference to the object. Instead, I should use Owned<>:
public class MyClass
{
public MyClass(Owned<A> a)
{
a.Value.Dosomething();
a.Dispose();
}
}
or use the ExternallyOwned registration modifier:
builder.RegisterAssemblyTypes(Assembly.GetExecutingAssembly()).ExternallyOwned();
later on, I should be able to use a = null to release the object to the GC.
Is that right?
Thanks!
By default, you don't need to dispose anything - Autofac will automatically identify and dispose any IDisposable instances it created when their containing lifetime scope is disposed.
You only need to use Owned<T> or ExternallyOwned() if you have a reason to manage the lifetime of the object manually. If you resolve an Owned<T> then you should call t.Dispose() yourself - the common usage pattern is to take a dependency on a factory delegate:
public class MyClass
{
private Func<Owned<User>> myDisposableFactory;
public MyClass(Func<Owned<User>> myDisposableFactory)
{
this.myDisposableFactory = myDisposableFactory;
}
public void DoSomething()
{
using (var disposable = this.myDisposableFactory())
{
// ...
disposable.Dispose();
}
}
}
If you register a type as ExternallyOwned() then Autofac will not dispose of any resolved instance when the containing lifetime scope ends - it's up to you to manage it.
Take a look at Nicholas Blumhardt's article on lifetimes for more information.