I'm trying to run some javascript from a .NET class library using JSPool and JavaScriptEngineSwitcher.V8, but I can't work out how to install JavaScriptEngineSwitcher.V8. My code so far is simple
public class Renderer : IDisposable
{
private readonly JsPool _pool;
private static readonly string[] _requiredFiles = { "vendors", "app" };
public Renderer(string jsPath)
{
_pool = new JsPool(new JsPoolConfig
{
Initializer = initEngine =>
{
foreach (var file in _requiredFiles)
{
initEngine.ExecuteFile(jsPath + "\\" + file + ".js");
}
}
});
}
public string Render()
{
using (var engine = _pool.GetEngine())
{
return engine.Evaluate<string>(#"myjsFn()");
}
}
public void Dispose()
{
_pool.Dispose();
}
}
But this throws a NullRefException as no engine has been registered
NullReferenceException: Object reference not set to an instance of an object.
JavaScriptEngineSwitcher.Core.JsEngineSwitcher.CreateDefaultJsEngineInstance()
My app is targeting dnx451, and I've specified JSPool 0.4.1 and JavaScriptEngineSwitcher.V8 1.5.8 in my dependencies. I've had a good look but can't seem to find anything that shows any code required to register the V8 engine. Can anyone point me in the right direction?
This problem was solved in the JavaScript Engine Switcher version 2.0.0 and JSPool version 2.0.0. Before installing of NuGet packages, I recommend to first read “How to upgrade applications to version 2.X” section of the documentation.
But worth noting, that the JavaScriptEngineSwitcher.V8 module can be used only in web application created by the “ASP.NET Core Web Application (.NET Framework)” template.
Related
I've written a C# class library for my company to use internally, and it uses DotNet UserSecrets to allow each developer to have their own credentials set without needing to worry about accidentally committing them. It worked fine during testing, but after installing it as a NuGet package as opposed to a project dependency, it no longer seems to be able to read from the secrets.json file. I'm wondering if this is a security thing that C# prevents, or if I need to do something else to enable that functionality in an external package.
The package code looks like this:
using Microsoft.Extensions.Configuration;
using TechTalk.Specflow;
namespace Testing.Utilities
{
[Binding]
public class Context
{
private static IConfigurationRoot configuration { get; set; }
private static FeatureContext feature_context;
// SpecFlow attribute runs this before anything else executes
[BeforeFeature(Order = 1)]
private static void SetFeatureContext(FeatureContext context)
{
try
{
configuration = new ConfigurationBuilder()
.AddUserSecrets<Context>()
.Build();
}
catch { }
feature_context = context;
test_context = context.FeatureContainer.Resolve<TestContext>();
}
public static string GetSecretVariable(string name)
{
object v = null;
// if the user secrets were found
if (configuration != null)
{
v = configuration[name];
}
if (v == null)
{
Logger.Warning($"secret variable '{name}' not found");
return null;
}
return v.ToString();
}
}
}
And in the calling code which always gets Null from the getter method:
using Testing.Utilities; // via NuGet package
namespace Testing
{
public static void Main()
{
System.Console.WriteLine($"found {Context.GetSecretVariable("super_secret")}");
}
}
Update:
It works as expected when I drag my locally built .nupkg file into my NuGet package cache and replace the one pulled from the repo. I updated the version number and pushed the change so I know they are on the same version, and it still only worked when I manually inserted my build. Now I'm more confused...
I ported the project from .NET Framework 4.6.1 to .NET 6 and it seemed to fix it. Kinda drastic change, but easy enough refactor and 461 is EOL anyways.
I am working with a project in .net core 2.2 and I am trying to use one class from a reference coded in .Net 4.6 .
When I try to use it in my .net core project, it seems like intelisense recognizes the reference and I can nagivate to it, but it also tells me the error of the title.
I don't know what is going on but I think it could be some stuff about working with .net core and .Net 4.6.
This is the class (.Net 4.6):
class ConfigServices : IEnumerable<ConfigService>, IEnumerable
{
public ConfigServices(IEnumerable<ConfigService> configServices, string activeService);
public ConfigService ActiveService { get; }
public bool IsEmpty { get; }
public bool Contains(ConfigService service);
public IEnumerator<ConfigService> GetEnumerator();
}
Here is where I am getting the error (first line of method)(.Net core) :
private async Task<string[]> configServicesToUse(string companyId, string serviceName)
{
var configServicesForCompany = (await UserInfo.ConfigServices(companyId)).Select(c => c.Name).ToArray();
if (string.IsNullOrWhiteSpace(serviceName) ||
string.Equals(serviceName, "ALL", StringComparison.InvariantCultureIgnoreCase))
{
return configServicesForCompany;
}
if (!configServicesForCompany.Contains(serviceName))
{
throw new UnauthorizedAccessException("No access to requested service");
}
return new[] { serviceName };
}
This is the method called (.Net core):
public static async Task<ConfigServices> ConfigServices(string companyId)
{
var configurationService = new ConfigurationService();
var services = await configurationService.ReadByCompanyId(int.Parse(companyId));
return new ConfigServices(services, ActiveConfigService);
}
The error I am getting is
"Error CS7068 Reference to type 'ConfigServices' claims it is defined
in this assembly, but it is not defined in source or any added
modules".
I looked for answers but they were to specific for
frameworks and things I am not using.
I hope you can help me,
Thank you in advance :)
Finally I got the problem. This error was happening because I had the same namespace reference in my project as it was in one of the nuget packages. That was making Visual Studio to get really confused with the existance of the ConfigServices class.
I'm just taking my first baby steps in the MEF territory and wanted to do so using .net core 2.1.
Using VS 2017 (version 15.8.8) I've done a small Console App (.NET Core) with an interface
interface IMessageSender
{
void Send(string message);
}
and an implementation (in the same project)
[Export(typeof(IMessageSender))]
public class EmailSender : IMessageSender
{
public void Send(string message)
{
Console.WriteLine("EmailSender : " + message);
}
}
Finally I have a small compose method executed from my Main(string[] args)
[Import]
private void Compose()
{
var assembly_A = new[] { typeof(Program).GetTypeInfo().Assembly };
var config_A = new ContainerConfiguration().WithAssembly(assembly_A[0]);
var container_A = config_A.CreateContainer();
var msg_A = container_A.GetExport<IMessageSender>();
msg_A.Send("Hello");
}
It works as expected
However, if I add a new class library to my solution and move my implementation of Send(string) to the newly added project things do not work out.
namespace AnotherMefExtensionProjectNamespace
{
[Export(typeof(IMessageSender))]
public class EmailSenderExtended : IMessageSender
{
public void Send(string message)
{
Console.WriteLine("EmailSenderExtended : " + message);
}
}
}
The new Compose method
[Import]
public IMessageSender MessageSender { get; set; }
private void Compose()
{
var assembly_B = new[] { typeof(EmailSenderExtended).GetTypeInfo().Assembly };
var config_B = new ContainerConfiguration().WithAssembly(assembly_B[0]);
var container_B = config_B.CreateContainer();
var msg_B = container_B.GetExport<IMessageSender>();
msg_B.Send("Hello");
}
I've tried to compare the different configs and containers (_A versus _B in the examples) but can't understand what is different. I've even tried to extend the class ContainerConfiguration to load from a specified assembly and it works as long as the given file contains the Main method but fails if I use my "extended" .NET Core Class Library.
public static ContainerConfiguration WithChosenAssembly(this ContainerConfiguration configuration, string pathAndFile)
{
var context = AssemblyLoadContext.Default.LoadFromAssemblyPath(pathAndFile);
var ass_list = new List<Assembly>() { context };
configuration = configuration.WithAssemblies(ass_list, null);
return configuration;
}
I was under the impression that you extend your main application by developing a class library that basically implements the interfaces specified.
I seem to be unable to do this currently, but obviously I misunderstood something very basic.
If someone would care to put me on the right track or give me an alternative idea for "plug-in" development for .net core I would be very grateful.
King regards
Magnus
I realized that my test setup does not mimic any real world scenario and thus I brought my problems on myself.
Obviously I should have had three projects.
One project with only the interface definitions.
One "main" project where all my regular code exists.
One (or more) projects where my MEF implementations of the interfaces exist.
Reviewing my example and adhering to the obvious "design" above it all works exactly as it should.
Most StackOverflow users probably wouldn't make my blunder but for those that did, I hope the above helps. :-)
I'm using Squirrel.Windows as an update framework for my application and I upgraded from 1.4.4 to the latest version 1.5.2 and after upgrading via NuGet the UpdateManager class became inaccessible due to it's protection level.
I created a sample project and imported the Squirrel.Windows nuget package via NuGet and I was able to instantiate an instance of the UpdateManager class without issue.
I tried cleaning out all the NuGet packages related to the Squirrel.Windows project and cleaned up any information remaining in the csproj that was related to it, after importing the package again I was still unable to access the class.
namespace Our.Core
{
public class Launcher
{
public static void Main(string[] args)
{
new Launcher(args);
}
public async Task<bool> TryUpdate(string[] args)
{
try
{
using (var mgr = new UpdateManager(UpdatePath, null, null, null))
{
Log.Information("Checking for updates");
var updateInfo = await mgr.CheckForUpdate();
if (updateInfo.ReleasesToApply.Any())
{
Log.Information("Downloading updates");
await mgr.DownloadReleases(updateInfo.ReleasesToApply);
Log.Information("Applying updates");
await mgr.ApplyReleases(updateInfo);
return true;
}
Log.Information("No updates found.");
return false;
}
}
catch (Exception e)
{
Log.Error(e, "Error while updating");
return false;
}
}
}
}
The problem turned out to be that after upgrading the library, the reference in the project had its Specific Version property toggled to false. This caused Visual Studio to be unable to correctly reference the correct version of the library.
Moral of the story, make sure to check your version and that your specific version check is true if you need to use a specific version!
I am being prompted for a file called EnumerableExtensions.cs when using the NHibernateFacility for Castle Windsor. I have replicated this with the following steps (all packages were installed from NuGet):
Create a new WPF project
Install Castle.Core 3.1.0
Install Castle.Windsor 3.1.0
Install Castle.FactorySupportFacility 3.1.0
Install Castle.Transactions 3.2.207.2207
Install Castle.Facilities.AutoTx 3.2.207.2207
Install NHibernate 3.3.1.4000
Install Fluent NHibernate 1.3.0.733
Install Castle.Facilities.NHibernate 0.7.1.23602
Override OnStartup() in App.xaml.cs to create the Windsor container and add the facilities to it. See code below.
protected override void OnStartup(StartupEventArgs e)
{
base.OnStartup(e);
IWindsorContainer container = new WindsorContainer();
container.AddFacility<AutoTxFacility>();
container.Register(
Component.For<INHibernateInstaller>()
.ImplementedBy<FluentNHibernateInstaller>());
container.AddFacility<NHibernateFacility>();
}
This is the code in FluentNHibernateInstaller.cs
public class FluentNHibernateInstaller : INHibernateInstaller
{
public FluentConfiguration BuildFluent()
{
return Fluently.Configure();
}
private IPersistenceConfigurer SetupDatabase()
{
return MsSqlConfiguration.MsSql2008
.ConnectionString(c => c
.Server("Server")
.Database("Database")
.Username("User")
.Password("Password"));
}
public Maybe<NHibernate.IInterceptor> Interceptor
{
get { return Maybe.None<NHibernate.IInterceptor>(); }
}
public bool IsDefault
{
get { return true; }
}
public void Registered(ISessionFactory factory)
{
}
public string SessionFactoryKey
{
get { return "sf.default"; }
}
}
When I run the application, this is the dialog I am presented with:
To me this looks like something is wrong with the DLL but when I posted about this on the Castle Project Google Group it was suggested that I had incompatible versions of Windsor in my app. Is this true or does it seem like something else is going on?
That dialog is Visual Studio asking for the source code of the file where an exception originated. Click cancel, and Visual Studio will instead stop somewhere in your own code and display the exception.
You can prevent the dialog by removing the pdb-file for the component in which the exception occurs (but that will also lead to less useful stack traces in case you want to report a bug in the affected component).