Announcement

Collapse
No announcement yet.

Partner 728x90

Collapse

BinaryFormatter - Accord .NET libraries

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

    BinaryFormatter - Accord .NET libraries

    I am working with the Accord .NET libraries, generally everything works.

    I can use the BinaryFormatter to save the model, but I cannot use it to load models. I keep getting this error:

    System.Runtime.Serialization.SerializationExceptio n: Unable to find assembly 'Accord.Statistics, Version=3.0.2.0, Culture=neutral, PublicKeyToken=fa1a88e29555ccf7'.
    at System.Runtime.Serialization.Formatters.Binary.Bin aryAssemblyInfo.GetAssembly()
    at System.Runtime.Serialization.Formatters.Binary.Obj ectReader.GetType(BinaryAssemblyInfo assemblyInfo, String name)
    at System.Runtime.Serialization.Formatters.Binary.Obj ectMap..ctor(String objectName, String[] memberNames, BinaryTypeEnum[] binaryTypeEnumA, Object[] typeInformationA, Int32[] memberAssemIds, ObjectReader objectReader, Int32 objectId, BinaryAssemblyInfo assemblyInfo, SizedArray assemIdToAssemblyTable)
    at System.Runtime.Serialization.Formatters.Binary.__B inaryParser.ReadObjectWithMapTyped(BinaryObjectWit hMapTyped record)
    at System.Runtime.Serialization.Formatters.Binary.__B inaryParser.Run()
    at System.Runtime.Serialization.Formatters.Binary.Obj ectReader.Deserialize(HeaderHandler handler, __BinaryParser serParser, Boolean fCheck, Boolean isCrossAppDomain, IMethodCallMessage methodCallMessage)
    at System.Runtime.Serialization.Formatters.Binary.Bin aryFormatter.Deserialize(Stream serializationStream)
    at NinjaTrader.NinjaScript.Indicators.Accord.PivotFin der.ExecuteCommand(String command) in c:\Users\Greg\Documents\NinjaTrader 8\bin\Custom\Indicators\Accord\PivotFinder.cs:line 372
    at NinjaTrader.NinjaScript.Indicators.Accord.PivotFin der.TextBox_PreviewKeyDown(Object sender, KeyEventArgs e) in c:\Users\Greg\Documents\NinjaTrader 8\bin\Custom\Indicators\Accord\PivotFinder.cs:line 278
    I have added the "bin\custom" directory to my system search path but it still doesn't seem to find the DLL listed there. NT8 has loaded the assembly, not sure why the formatter cannot find the copy in memory...

    Anyone have any ideas?
    Attached Files

    #2
    Originally posted by NJA_MC View Post
    I am working with the Accord .NET libraries, generally everything works.

    I can use the BinaryFormatter to save the model, but I cannot use it to load models. I keep getting this error:

    I have added the "bin\custom" directory to my system search path but it still doesn't seem to find the DLL listed there. NT8 has loaded the assembly, not sure why the formatter cannot find the copy in memory...

    Anyone have any ideas?
    Just a hunch, but I would first look at where you installed the indicator that is throwing errors. We may have some bug possibly with the way indicators are loaded against the assembly you're targeting within that additional sub-folder.

    Code:
    bin\Custom\Indicators\Accord\PivotFinder.cs
    As a test, try moving the indicator to the standard Bin\Custom\Indicator folder and try again.

    If you still have issues, I'm not quite sure what else may cause that, but I'd be interested to hear any other suggestions.
    MatthewNinjaTrader Product Management

    Comment


      #3
      Originally posted by NinjaTrader_Matthew View Post
      Just a hunch, but I would first look at where you installed the indicator that is throwing errors. We may have some bug possibly with the way indicators are loaded against the assembly you're targeting within that additional sub-folder.

      Code:
      bin\Custom\Indicators\Accord\PivotFinder.cs
      As a test, try moving the indicator to the standard Bin\Custom\Indicator folder and try again.

      If you still have issues, I'm not quite sure what else may cause that, but I'd be interested to hear any other suggestions.
      Hi Matt,

      Tried it, still doing the same thing. Thanks for the possible idea though.

      Comment


        #4
        Well thanks for taking the time to eliminate that as a possibility. I did some searching but could not find anything conclusive, however maybe this link on MSDNs forums could generate some ideas for you: https://social.msdn.microsoft.com/Fo...forum=netfxbcl
        MatthewNinjaTrader Product Management

        Comment


          #5
          Originally posted by NinjaTrader_Matthew View Post
          Well thanks for taking the time to eliminate that as a possibility. I did some searching but could not find anything conclusive, however maybe this link on MSDNs forums could generate some ideas for you: https://social.msdn.microsoft.com/Fo...forum=netfxbcl
          Thanks Matt,

          I think I have the best solution. This might actually be something you can add into the NT8 core to help resolve other issues. I have left some debugging lines in so you and the development team can review. Ultimately, I have added an AppDomain.CurrentDomain.AssemblyResolve event, and removed it afterwards to make sure it doesn't mess up other code.

          Code:
                              {
                                  AppDomain.CurrentDomain.AssemblyResolve +=
                                                  new ResolveEventHandler(CurrentDomain_AssemblyResolve);
              
                                  using (FileStream fs = new FileStream(m_modelFile, FileMode.Open))
                                  {
                                      kda = new BinaryFormatter().Deserialize(fs) as KernelDiscriminantAnalysis;
                                  }                             
          
                                  AppDomain.CurrentDomain.AssemblyResolve -= new ResolveEventHandler(CurrentDomain_AssemblyResolve);                            
                              }
          Here is the additional Resolver added to my indicator:

          Code:
                  static Assembly CurrentDomain_AssemblyResolve(object sender, ResolveEventArgs args) 
                  {
                      Assembly ayResult = null;
          
                      NinjaTrader.Code.Output.Process("Args.Name="+args.Name,PrintTo.OutputTab1);
          
                      string sShortAssemblyName = args.Name.Split(',')[0];
          
                      Assembly[] ayAssemblies = AppDomain.CurrentDomain.GetAssemblies();
          
                      foreach (Assembly ayAssembly in ayAssemblies) 
                      {
                          if (sShortAssemblyName == ayAssembly.FullName.Split(',')[0]) {
                              
                              NinjaTrader.Code.Output.Process("Loading ayAssembly.FullName="+ayAssembly.FullName,PrintTo.OutputTab1);
          
                              ayResult = ayAssembly;
                              break;
                          }
                      }
          
                      return ayResult;
                  }
          Here is what is printed, you can even see the internal NinjaTrader assemblies loaded:
          Args.Name=Accord.Statistics, Version=3.0.2.0, Culture=neutral, PublicKeyToken=fa1a88e29555ccf7
          Loading ayAssembly.FullName=Accord.Statistics, Version=3.0.2.0, Culture=neutral, PublicKeyToken=fa1a88e29555ccf7
          Args.Name=NinjaTrader.Gui.XmlSerializers, Version=8.0.0.9, Culture=neutral, PublicKeyToken=null
          Args.Name=NinjaTrader.Gui.XmlSerializers
          Args.Name=NinjaTrader.Gui.XmlSerializers, Version=8.0.0.9, Culture=neutral, PublicKeyToken=null
          Args.Name=NinjaTrader.Gui.XmlSerializers
          Args.Name=NinjaTrader.Gui.XmlSerializers, Version=8.0.0.9, Culture=neutral, PublicKeyToken=null
          Args.Name=NinjaTrader.Gui.XmlSerializers
          Args.Name=NinjaTrader.Gui.XmlSerializers, Version=8.0.0.9, Culture=neutral, PublicKeyToken=null
          Args.Name=NinjaTrader.Gui.XmlSerializers
          Args.Name=NinjaTrader.Core.XmlSerializers, Version=8.0.0.9, Culture=neutral, PublicKeyToken=null
          Args.Name=NinjaTrader.Core.XmlSerializers
          Args.Name=NinjaTrader.Gui.XmlSerializers, Version=8.0.0.9, Culture=neutral, PublicKeyToken=null
          Args.Name=NinjaTrader.Gui.XmlSerializers
          Args.Name=NinjaTrader.Gui.XmlSerializers, Version=8.0.0.9, Culture=neutral, PublicKeyToken=null
          Args.Name=NinjaTrader.Gui.XmlSerializers
          Args.Name=NinjaTrader.Gui.resources, Version=8.0.0.9, Culture=en-US, PublicKeyToken=null
          Args.Name=NinjaTrader.Gui.resources, Version=8.0.0.9, Culture=en-US, PublicKeyToken=null
          Now when I load my Accord .NET model, the Assembly is extracted from those already loaded. This was the cleanest solution I tried. Many other ways to get this to work, but this is clearly the cleanest. Please consider adding this resolver to the NT8 core so this complexity can be removed from the NinjaScript code.

          Comment


            #6
            I used for NT8 next solution
            for example
            internal void Save(Stream stream)
            {
            BinaryFormatter formatter = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.CrossAppDo main));
            formatter.AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterA ssemblyStyle.Simple;
            formatter.Serialize(stream, this);
            }

            internal Network Load(Stream stream)
            {
            Network network = new Network(4, 16, 2);
            BinaryFormatter formatter = new BinaryFormatter(null, new StreamingContext(StreamingContextStates.CrossAppDo main));
            formatter.AssemblyFormat = System.Runtime.Serialization.Formatters.FormatterA ssemblyStyle.Simple;
            formatter.Binder = new MyBinder();
            try
            {
            network = (Network)formatter.Deserialize(stream);
            }
            catch (Exception ex)
            {
            Debug.Print("Error: " + ex);
            }
            return network;
            }

            internal sealed class MyBinder : SerializationBinder
            {
            public override Type BindToType(string assemblyName, string typeName)
            {
            Type typeToDeserialize = null;
            string currentAssemblyInfo = Assembly.GetExecutingAssembly().FullName;

            //my modification
            string currentAssemblyName = currentAssemblyInfo.Split(',')[0];
            if (assemblyName.StartsWith(currentAssemblyName)) assemblyName = currentAssemblyInfo;

            typeToDeserialize = Type.GetType(string.Format("{0}, {1}", typeName, assemblyName));
            return typeToDeserialize;
            }
            }
            Last edited by alexr; 02-28-2016, 08:03 PM.

            Comment


              #7
              I'll pass this over to the developers. Unfortunately its not 100% clear to me what the exact problem is your fixing or how your fixing it.

              Comment

              Latest Posts

              Collapse

              Topics Statistics Last Post
              Started by PaulMohn, Today, 03:49 AM
              0 responses
              2 views
              0 likes
              Last Post PaulMohn  
              Started by inanazsocial, Today, 01:15 AM
              1 response
              6 views
              0 likes
              Last Post NinjaTrader_Jason  
              Started by rocketman7, Today, 02:12 AM
              0 responses
              10 views
              0 likes
              Last Post rocketman7  
              Started by dustydbayer, Today, 01:59 AM
              0 responses
              2 views
              0 likes
              Last Post dustydbayer  
              Started by trilliantrader, 04-18-2024, 08:16 AM
              5 responses
              23 views
              0 likes
              Last Post trilliantrader  
              Working...
              X