oleg-shilo / cs-script.core

.NET Core port of CS-Script
MIT License
100 stars 18 forks source link

Hosted Script Can't find Type in Host Assemblies #1

Closed TheColonel2688 closed 5 years ago

TheColonel2688 commented 5 years ago

I am getting the following error

(2,24): error CS0234: The type or namespace name 'Mocks' does not exist in the namespace 'RAL.Devices.Adam' (are you missing an assembly reference?)
(10,45): error CS0234: The type or namespace name 'Mocks' does not exist in the namespace 'RAL.Devices.Adam' (are you missing an assembly reference?)

If I change the script file's Build Action to "C# Compile" From "Content" and just instantiate the class like normal it works.

here is my script

using RAL.Manager.Configuration;
using RAL.Devices.Adam.Mocks;

//namespace CS_ScriptTest
//{
    public class UserConfigurationTest : UserConfigBase
    {
        public override void UserConfigLoad()
        {
            var test = new RAL.Devices.Adam.Mocks.Adam6051StatusConverterForPressMock(1);
        }
    }
//}

here is the test program

using CSScriptLib;
using RAL.Manager.Configuration;
using System;

namespace CS_ScriptTest
{
    class Program
    {
        static void Main(string[] args)
        {
            var UserConfigurationTest = CSScript.Evaluator
                                 .LoadFile<IUserConfig>("UserConfigurationTest.cs");
        }
    }
}

If you need more information please let me know.

oleg-shilo commented 5 years ago

You need to reference your assembly. Let's assume your RAL.Devices.Adam.Mocks namespace is implemented in the assembly RAL.Devices.Adam.Mocks.dll. Then you can reference it with one of the appropriate ReferenceAssembly* methods:

var UserConfigurationTest = CSScript.Evaluator
                                    .ReferenceAssemblyByNamespace("RAL.Devices.Adam.Mocks")
                                    .ReferenceAssemblyByName("RAL.Devices.Adam.Mocks")
                                    .ReferenceAssembly("..\..\RAL.Devices.Adam.Mocks.dll")
                                    .ReferenceAssembly(typeof(RAL.Devices.Adam.Mocks.Mock).Assembly)
                                    .ReferenceAssemblyOf<RAL.Devices.Adam.Mocks.Mock>()
                                    .ReferenceAssemblyOf(mockObject)
                                    .LoadFile<IUserConfig>("UserConfigurationTest.cs");
TheColonel2688 commented 5 years ago

var UserConfigurationTest = CSScript.Evaluator.ReferenceAssemblyByNamespace("RAL.Devices.Adam.Mocks").LoadFile<IUserConfig>("UserConfigurationTest.cs"); Did not work, the actual assembly that the namespace is in is RAL.Devices.Mocks.dll

So I tried var UserConfigurationTest = CSScript.Evaluator.ReferenceAssemblyByName("RAL.Devices.Mocks")).LoadFile<IUserConfig>("UserConfigurationTest.cs");

That DID work. I do not know why the first didn't work. That is the correct namespace for the type used in the script.

Did I miss these methods in the documentation? I did look before I posted, but didn't find anything.

oleg-shilo commented 5 years ago

Great.

As for ReferenceAssemblyByNamespace it is expected to fail if the namespace does not match assembly name. There is no deterministic way of finding assembly by the namespace. Thus ReferenceAssemblyByNamespace does implement very simplistic probing algorithm (pseudo code):

Evaluator ReferenceAssemblyByNamespace(string namespace)
{
    ReferenceAssembly(namespace+".dll");
    ReferenceAssembly(namespace+".exe");
    return this;
} 

Thus when you know the assembly file name you should always prefer ReferenceAssembly as you did.

TheColonel2688 commented 5 years ago

Makes sense. Thank You