Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Use without extra dependencies #1

Closed
RobertBeekman opened this issue Aug 20, 2021 · 5 comments
Closed

Use without extra dependencies #1

RobertBeekman opened this issue Aug 20, 2021 · 5 comments
Assignees
Labels
enhancement New feature or request good first issue Good for newcomers question Further information is requested

Comments

@RobertBeekman
Copy link

Hello,

I'd love to use this library in a dekstop application but I'd really rather stay away from a dependency on Microsoft.Extensions.DependencyInjection and friends.

Is it possible to use this without adding that dependency? I'm using Ninject.

Thanks in advance!

@KovtunV
Copy link
Owner

KovtunV commented Aug 21, 2021

Hello @SpoinkyNL,

for sure you can, I suggest two ways:

1) Using Ninject

public class Program
{
    static async Task Main(string[] args)
    {
        var kernel = new StandardKernel();
        kernel.Load(Assembly.GetExecutingAssembly());

        var eval = kernel.Get<INoStringEvaluator>();

        var res1 = eval.CalcNumber("5 - 36"); // -31
        var res2 = eval.CalcWord("5 + \"happy\""); // !5happy!
        var res3 = eval.CalcNumber("max(1; 5; 5; 3; 45; 7) - min(5; 7; 5; 2; 4)"); // 43
        var res4 = eval.CalcWord("YouAre('Vitaly'; 26)"); // !Hello, Vitaly. After 10 years you will be 36 y.o.!
    }
}

NinjectModule

public class NoStringNinjectModule : NinjectModule
{
    public override void Load()
    {
        // Pooling
        Bind<ObjectPool<Stack<InternalEvaluatorValue>>>()
            .ToConstant(ObjectPool.Create<Stack<InternalEvaluatorValue>>())
            .InSingletonScope();

        Bind<ObjectPool<List<InternalEvaluatorValue>>>()
            .ToConstant(ObjectPool.Create<List<InternalEvaluatorValue>>())
            .InSingletonScope();

        Bind<ObjectPool<ExtraTypeIdContainer>>()
            .ToConstant(ObjectPool.Create<ExtraTypeIdContainer>())
            .InSingletonScope();

        // Parser
        Bind<IFormulaCache>().To<FormulaCache>().InSingletonScope();
        Bind<IFunctionReader>().To<FunctionReader>().InSingletonScope();
        Bind<IFormulaParser>().To<FormulaParser>().InSingletonScope();

        // Checker
        Bind<IFormulaChecker>().To<FormulaChecker>().InSingletonScope();

        // Evaluator
        Bind<INoStringEvaluator>().To<NoStringEvaluator>().InSingletonScope();

        // Options
        var opt = new NoStringEvaluatorOptions().SetWordQuotationMark("!");
        opt.UpdateConstants();

        // If needed
        InjectUserDefinedFunctions();
    }

    private void InjectUserDefinedFunctions()
    {
        var functionReader = Kernel.GetRequiredService<IFunctionReader>();
        NoStringFunctionsInitializer.InitializeFunctions(functionReader, typeof(NoStringNinjectModule));
    }
}

2) Using manual initialization - not recommended, but it's possible 😃

public class Program
{
    static async Task Main(string[] args)
    {
        var evalInstance = new EvaluatorInstance();
        var eval = evalInstance.Evaluator;

        var res1 = eval.CalcNumber("5 - 36"); // -31
        var res2 = eval.CalcWord("5 + \"happy\""); // !5happy!
        var res3 = eval.CalcNumber("max(1; 5; 5; 3; 45; 7) - min(5; 7; 5; 2; 4)"); // 43
        var res4 = eval.CalcWord("YouAre('Vitaly'; 26)"); // !Hello, Vitaly. After 10 years you will be 36 y.o.!
    }
}

EvaluatorInstance

public class EvaluatorInstance
{
    private readonly ObjectPool<Stack<InternalEvaluatorValue>> _stackPool;
    private readonly ObjectPool<List<InternalEvaluatorValue>> _argsPool;
    private readonly ObjectPool<ExtraTypeIdContainer> _extraTypeIdPool;

    public EvaluatorInstance()
    {
        // Pooling
        _stackPool = ObjectPool.Create<Stack<InternalEvaluatorValue>>();
        _argsPool = ObjectPool.Create<List<InternalEvaluatorValue>>();
        _extraTypeIdPool = ObjectPool.Create<ExtraTypeIdContainer>();

        // Parser
        FunctionReader = new FunctionReader();
        FormulaParser = new FormulaParser(FunctionReader);
        FormulaCache = new FormulaCache(FormulaParser);

        // Checker
        FormulaChecker = new FormulaChecker(FormulaParser);

        // Evaluator
        Evaluator = new NoStringEvaluator(_stackPool, _argsPool, _extraTypeIdPool, FormulaCache);

        // Options
        var opt = new NoStringEvaluatorOptions().SetWordQuotationMark("!");
        opt.UpdateConstants();

        // If needed
        InitializeUserDefinedFunctions();
    }

    public INoStringEvaluator Evaluator { get; }

    public IFunctionReader FunctionReader { get; }

    public IFormulaParser FormulaParser { get; }

    public IFormulaCache FormulaCache { get; }

    public IFormulaChecker FormulaChecker { get; }

    private void InitializeUserDefinedFunctions()
    {
        NoStringFunctionsInitializer.InitializeFunctions(FunctionReader, typeof(NoStringNinjectModule));
    }
}

@KovtunV KovtunV self-assigned this Aug 21, 2021
@KovtunV KovtunV added good first issue Good for newcomers question Further information is requested labels Aug 21, 2021
@KovtunV
Copy link
Owner

KovtunV commented Aug 21, 2021

BTW, @SpoinkyNL, if Microsoft.Extensions.DependencyInjection dependency shouldn't be, I can split nuget and make two

  • NoStringEvaluating - only evaluator with Microsoft.Extensions.ObjectPool dependency
  • NoStringEvaluating.Extensions.Microsoft.DependencyInjection - extension for this IoC

Would it be good?

@RobertBeekman
Copy link
Author

Hey, thanks for the reply and code sample!

A separate Nuget package sounds great, if it's not too much trouble.

The dependency on ObjectPool is ofcourse no problem :)

I'll be using this to power a Maths node in our node-based visual scripting system for https://github.com/Artemis-RGB/Artemis

@KovtunV KovtunV added the enhancement New feature or request label Aug 21, 2021
@KovtunV
Copy link
Owner

KovtunV commented Aug 21, 2021

@SpoinkyNL

I've just launched

  1. v2.2.1 https://www.nuget.org/packages/NoStringEvaluating
  2. Microsoft DI https://www.nuget.org/packages/NoStringEvaluating.Extensions.Microsoft.DependencyInjection

If you need anything else let me know, please 😊
Have a good day!

@RobertBeekman
Copy link
Author

Hi, this turned out great, thank you!

img

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request good first issue Good for newcomers question Further information is requested
Projects
None yet
Development

No branches or pull requests

2 participants