# Argument as interface types

**URL:** https://discuss.hangfire.io/t/argument-as-interface-types/1189
**Category:** bug?
**Created:** [August 2, 2015, 9:35pm UTC](https://discuss.hangfire.io/t/argument-as-interface-types/1189 "2015-08-02T21:35:01Z")
**Posts on this page:** 11
**Page:** 1

<div class="post-metadata">

### Author: ![AdamBarclay](https://dub1.discourse-cdn.com/flex017/user_avatar/discuss.hangfire.io/adambarclay/32/319_2.png) [@AdamBarclay](https://discuss.hangfire.io/u/AdamBarclay)
#### Post date: [August 2, 2015, 9:35pm UTC](https://discuss.hangfire.io/t/argument-as-interface-types/1189/1 "2015-08-02T21:35:01Z")

</div>

I’m migrating from using a custom task runner for our app to Hangfire. The current implementation has the concept of tasks as a message and handler (`ITask` and `ITaskHandler`).

To keep this concept and avoid reworking a lot of code I have a small snippet to integrate Hangfire with Hangfire:

```auto
public void Execute(ITask task)
{
    BackgroundJob.Enqueue<ImmediateTaskExecutor>(e => e.Execute(task));
}

```

The problem is one execution of the background task the argument is not actually created (passed to the `ImmediateTaskExecutor` as `null`). I believe this is because the runtime type is not stored with the argument, only the static type (e.g. `ITask` is stored in the database not `TheTaskThatImplementsITask`).

Is there a way around this for now and should this be considered a bug?

Cheers,  
Adam

---

<div class="post-metadata">

### Author: ![nirinchev](https://dub1.discourse-cdn.com/flex017/user_avatar/discuss.hangfire.io/nirinchev/32/122_2.png) [@nirinchev](https://discuss.hangfire.io/u/nirinchev)
#### Post date: [August 2, 2015, 10:43pm UTC](https://discuss.hangfire.io/t/argument-as-interface-types/1189/2 "2015-08-02T22:43:06Z")

</div>

I would be very surprised if the runtime type was not properly serialized. I don’t recall if we have a similar case in our project (and can’t check now), but you can inspect the scheduled task in the dashboard and see the serialized argument - maybe that will give you some insight as to what’s going on.

---

<div class="post-metadata">

### Author: ![AdamBarclay](https://dub1.discourse-cdn.com/flex017/user_avatar/discuss.hangfire.io/adambarclay/32/319_2.png) [@AdamBarclay](https://discuss.hangfire.io/u/AdamBarclay)
#### Post date: [August 3, 2015, 8:15am UTC](https://discuss.hangfire.io/t/argument-as-interface-types/1189/3 "2015-08-03T08:15:28Z")

</div>

Thanks for the reply. In the dashboard I can see the generated code:

```
using Blueprint.Core.Tasks;

ImmediateTaskExecutor immediateTaskExecutor = Activate<ImmediateTaskExecutor>();
immediateTaskExecutor.Execute(
    Deserialize<ITask>("{\"CreatedAt\":\"2015-08-02T18:29:24.9869395+00:00\",\"ProjectId\":80456868}"));

```

I take it from that code that the task that would be created would be of type `ITask`, which of course will not be correct as that is an interface type with no parameters (just a marker interface)

Looking in `Hangfire.Job` SQL job table I see, in InvocationData:

```
{"Type":"Blueprint.Core.Tasks.ImmediateTaskExecutor, Blueprint.Core, Version=3.6.7.0, Culture=neutral, PublicKeyToken=null","Method":"Execute","ParameterTypes":"[\"Blueprint.Core.Tasks.ITask, Blueprint.Core, Version=3.6.7.0, Culture=neutral, PublicKeyToken=null\"]","Arguments":"[\"{\\\"CreatedAt\\\":\\\"2015-08-02T18:29:24.9869395+00:00\\\",\\\"ProjectId\\\":80456868}\"]"}
```

---

<div class="post-metadata">

### Author: ![AdamBarclay](https://dub1.discourse-cdn.com/flex017/user_avatar/discuss.hangfire.io/adambarclay/32/319_2.png) [@AdamBarclay](https://discuss.hangfire.io/u/AdamBarclay)
#### Post date: [August 3, 2015, 4:08pm UTC](https://discuss.hangfire.io/t/argument-as-interface-types/1189/4 "2015-08-03T16:08:00Z")

</div>

I have created an example that shows the problem I am running in to, based off of the minimal Hangfire sample console app:

> **[Dropbox - Error](https://www.dropbox.com/s/5xakav9lkbbibao/Hangfire%20Interface%20Argument%20Bug%20Example.zip?dl=0)**
>
> Dropbox is a free service that lets you bring your photos, docs, and videos anywhere and share them easily. Never email yourself a file again!

Hopefully that shows the problem better than just a text description

---

<div class="post-metadata">

### Author: ![odinserj](https://dub1.discourse-cdn.com/flex017/user_avatar/discuss.hangfire.io/odinserj/32/648_2.png) [@odinserj](https://discuss.hangfire.io/u/odinserj)
#### Post date: [August 4, 2015, 2:23pm UTC](https://discuss.hangfire.io/t/argument-as-interface-types/1189/5 "2015-08-04T14:23:35Z")

</div>

@AdamBarclay, serialized string of a job argument does not include the type name by default, and thus it can’t be deserialized. However, you can change this by passing your own serialization options:

```auto
JobHelper.SetSerializerSettings(
    new JsonSerializerSettings { TypeNameHandling = TypeNameHandling.All }); 

```

This will enable [Json.NET](http://Json.NET) to serialize your arguments with preserving the type information. Please try this.

---

<div class="post-metadata">

### Author: ![AdamBarclay](https://dub1.discourse-cdn.com/flex017/user_avatar/discuss.hangfire.io/adambarclay/32/319_2.png) [@AdamBarclay](https://discuss.hangfire.io/u/AdamBarclay)
#### Post date: [August 4, 2015, 2:41pm UTC](https://discuss.hangfire.io/t/argument-as-interface-types/1189/6 "2015-08-04T14:41:48Z")

</div>

@odinserj, I’ve just tried that but it results in an exception when the job is being run:

Newtonsoft.Json.JsonSerializationException

Type specified in JSON ‘System.Linq.Enumerable+WhereSelectArrayIterator`2[[System.Reflection.ParameterInfo, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089],[System.Type, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089]], System.Core, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089’ is not compatible with ‘System.Type[], mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089’. Path ‘$type’, line 1, position 142.

at Newtonsoft.Json.JsonConvert.DeserializeObject[T](String value, JsonSerializerSettings settings)  
at Hangfire.Common.JobHelper.FromJson[T](String value)  
at Hangfire.Storage.InvocationData.Deserialize()

The `Arguments` column in `Job` table now contains:

```
{"$type":"System.String[], mscorlib","$values":["{\"$type\":\"Hangfire.ConsoleApplication.GreetingTask, Hangfire.ConsoleApplication\",\"Greeting\":\"Hello world\"}"]}
```

---

<div class="post-metadata">

### Author: ![odinserj](https://dub1.discourse-cdn.com/flex017/user_avatar/discuss.hangfire.io/odinserj/32/648_2.png) [@odinserj](https://discuss.hangfire.io/u/odinserj)
#### Post date: [August 4, 2015, 2:47pm UTC](https://discuss.hangfire.io/t/argument-as-interface-types/1189/7 "2015-08-04T14:47:21Z")

</div>

@AdamBarclay, what Hangfire version are you using? [This PR](https://github.com/HangfireIO/Hangfire/pull/363) attempts to fix this in 1.4.3.

---

<div class="post-metadata">

### Author: ![AdamBarclay](https://dub1.discourse-cdn.com/flex017/user_avatar/discuss.hangfire.io/adambarclay/32/319_2.png) [@AdamBarclay](https://discuss.hangfire.io/u/AdamBarclay)
#### Post date: [August 4, 2015, 2:52pm UTC](https://discuss.hangfire.io/t/argument-as-interface-types/1189/8 "2015-08-04T14:52:02Z")

</div>

@odinserj I was using version 1.4.1 (the default version from Hangfire.Sample github, which I had assumed was the latest version).

Having upgraded to 1.4.5 that now fixes the exception posted. Perhaps the default should be to include the type names in the JSON being serialised? It pushes Hangfire a step further towards ‘just working’ without requiring any extra configuration. I don’t think my usage is particularly abnormal.

Or at a minimum perhaps somewhere in the documentation?

Many thanks for all your work! Looking forward to replacing our home-grown solution with something that actually works real nice 😄

---

<div class="post-metadata">

### Author: ![odinserj](https://dub1.discourse-cdn.com/flex017/user_avatar/discuss.hangfire.io/odinserj/32/648_2.png) [@odinserj](https://discuss.hangfire.io/u/odinserj)
#### Post date: [August 4, 2015, 3:06pm UTC](https://discuss.hangfire.io/t/argument-as-interface-types/1189/9 "2015-08-04T15:06:16Z")

</div>

> [@AdamBarclay](#):
>
> Perhaps the default should be to include the type names in the JSON being serialised? It pushes Hangfire a step further towards ‘just working’ without requiring any extra configuration. I don’t think my usage is particularly abnormal.

This is a breaking change, since objects serialized without `TypeNameHandling.All` should be de-serialized without this setting either. Need to think how to handle this.

---

<div class="post-metadata">

### Author: ![odinserj](https://dub1.discourse-cdn.com/flex017/user_avatar/discuss.hangfire.io/odinserj/32/648_2.png) [@odinserj](https://discuss.hangfire.io/u/odinserj)
#### Post date: [August 5, 2015, 1:10pm UTC](https://discuss.hangfire.io/t/argument-as-interface-types/1189/10 "2015-08-05T13:10:53Z")

</div>

I moved 2 posts to a new topic: [Use `TypeNameHandling.All` when serializing arguments by default](https://discuss.hangfire.io/t/use-typenamehandling-all-when-serializing-arguments-by-default/1200)

---

<div class="post-metadata">

### Author: ![odinserj](https://dub1.discourse-cdn.com/flex017/user_avatar/discuss.hangfire.io/odinserj/32/648_2.png) [@odinserj](https://discuss.hangfire.io/u/odinserj)
#### Post date: [August 5, 2015, 1:11pm UTC](https://discuss.hangfire.io/t/argument-as-interface-types/1189/11 "2015-08-05T13:11:16Z")

</div>


