First I'm going to answer your question matching your original code as closely as possible. Second, I'm going to show a far more concise example that might in fact be all that you're after.
You can certainly declare your type as you've done, but a few things will have to be fixed to even get it to make sense.
Your
SomethingDoer
class declares a non-staticInjectedService
property, despite the fact that you attempt to consume that property in a static method. I will assume for the sake of discussion that you intendedSomethingDoer.DoSomething
to be non-static as well and will thus instanatiate that class.public static bool DoSomething()
To:
public bool DoSomething()
The "sesion" you pass to
CreateSession
is your actual service. To understand why this won't work, you have to understand what the argument you pass toCreateSession
means and what's done with it. What the "session" means is that all the public properties of that object are available to your scripting session as raw identifiers without the need to.
reference them on any target. Thus, to get your code working, I've introduced a new class (inner to the main service class for convenience) calledSession
:public class Session { public IInjectedService InjectedService { get; set; } }
Furthermore, I've used this new class when invoking
CreateSession
:var session = engine.CreateSession(new Session { InjectedService = _injectedService });
What this means is that the property
InjectedService
is now available to you within yourcodeString
.Perhaps most importantly, your code
codeString
is never actually consumed by your code! You seem to have, understandably, conceived of this process as setting up a string for your code, and then imagined that you could then invoke some arbitrary method within it. On the contrary, there is only one block of code. So if you really want to declare a whole class in your script-code, you're still going to have to consume it directly within your script-code as well. This means that the final two lines of yourcodeString
should actually look like:var somethingDoer = new SomethingDoer { InjectedService = InjectedService }; somethingDoer.DoSomething()";
Here we're instantiating
SomethingDoer
(because of change 1.) and setting the service property by the implicitInjectedService
value provided by the session (because of change 2.).
For completeness, here is the fully working sample code:
namespace RoslynMVCTest.Interfaces
{
public interface IInjectedService
{
bool SomeOtherMethod();
}
}
namespace RoslynMVCTest.Services
{
using RoslynMVCTest.Interfaces;
class Program
{
static void Main(string[] args)
{
Console.WriteLine(new MyService(new InjectedService()).SomeMethod());
Console.ReadLine();
}
}
class InjectedService : IInjectedService
{
public bool SomeOtherMethod()
{
return true;
}
}
public class MyService
{
private readonly IInjectedService _injectedService;
public MyService(IInjectedService injectedService)
{
_injectedService = injectedService;
}
public class Session
{
public IInjectedService InjectedService { get; set; }
}
public bool SomeMethod()
{
string codeString = @"
using RoslynMVCTest.Interfaces;
public class SomethingDoer
{
public IInjectedService InjectedService { get; set; }
public bool DoSomething()
{
return InjectedService.SomeOtherMethod();
}
}
var somethingDoer = new SomethingDoer { InjectedService = InjectedService };
somethingDoer.DoSomething()";
var engine = new ScriptEngine();
var session = engine.CreateSession(new Session { InjectedService = _injectedService });
session.AddReference(this.GetType().Assembly);
//How do I set the property in my dynamic code to _injectedService??
var result = session.Execute<bool>(codeString);
return result;
}
}
}
Alternative Approach
If all you want to do is allow your script to run some code that interacts with your service, you can see how this is actually extremely trivial given all the points made above. Thus to concisely express what might be the intent of your original code, all you'd have to do is:
var result = session.Execute<bool>("InjectedService.SomeOtherMethod()");
The code passed in here is simply the body of the service method in the long-winded first example. Quite possibly this is all you need or want.