"AfterRead" event in the v2.0.0 version - c#

My goal is to change the value of a field after it is read. And I think it is possible running the "AfterRead" event.
My current version of the library is 2.0.0.
I have tested the next getting an error:
public class sealed MyClass: INotifyRead
{
// ...
public void AfterRead(EngineBase engine, AfterReadEventArgs e)
{
}
}
The error message is:
Cannot find the namespace "AfterReadEventArgs". Missing the "using" directive or assembly reference.
I have read the next code in the docs:
FileHelperEngine engine = new FileHelperEngine(typeof(Orders));
engine.BeforeReadRecord += new BeforeReadRecordHandler(BeforeEvent);
Orders[] res = engine.ReadFile("report.txt") as Orders[];
I don't know if it is needed to declare the delegate in the source code or it is enough the declaration of the event in the Mapping Class.
Thanks a lot!

The signature of the AfterRead event is different in 2.0.0.0. Here's a working example.
using System;
using System.Diagnostics;
using FileHelpers;
namespace ConsoleApp
{
[DelimitedRecord(";")]
public sealed class MyClass : INotifyRead
{
public string Field1;
public string Field2;
public void AfterRead(EngineBase engine, string line)
{
Field1 = "ModifiedValue1";
}
}
internal class Program
{
static void Main(string[] args)
{
FileHelperEngine engine = new FileHelperEngine(typeof(MyClass));
var records = engine.ReadString("Value1;Value2");
var firstRecord = records[0] as MyClass;
Debug.Assert(firstRecord.Field1 == "ModifiedValue1");
Console.Write("All OK. Field1 had the modified value.");
Console.ReadKey();
}
}
}

Related

Call method that has a Delegate instance parameter through Reflection C#

I have this C# code in an external assembly:
namespace Fancy
{
internal class Foo
{
public static void Window(string title, Foo.WindowFunction sceneViewFunc, int order)
{}
public delegate void WindowFunction(float x, float y);
}
}
And I have my code:
class A
{
public static void Draw(float x, float y)
{
// impl
}
static void Main(string[] args)
{
var newWindow = ?;
}
}
I want to call Fancy.Foo.Window() like
Fancy.Foo.Window("Window Name", new Foo.WindowFunction(A.Draw), 450);
inside my A class through Reflection.
How can I do it? Tried lot of different options no success :/
The documentation defines internal access modifier as follows
The type or member can be accessed by any code in the same assembly, but not from another assembly.
Not being able to access from outside of the assembly is the default and expected behaviour. But you can do that in multiple ways. If you have access to the source of the external assembly. You can mark your current assembly as a friend of the external assembly as shown below and recmpile it.
[assembly: InternalsVisibleTo("<Your assembly name>")]
Considering that you might not always have access to the source of external assembly, the same can be done using reflection by loading the assembly, creating an instance of the class and fetching the Non-Public members on the internal type. See how to access internal class using reflection. See also other ways to use internal class of another assembly.
Using reflection on external/third-party assemblies comes with its own caveats as the source of the assembly may change at any point in time, breaking your code.
Below is the code:
ClassLibrary1:
using System;
namespace ClassLibrary1
{
public class Foo
{
public static void Window(string title, WindowFunction sceneViewFunc, int order)
{
Console.WriteLine("Foo Window");
}
public delegate void WindowFunction(float x, float y);
}
}
Main Program.cs
using System;
using static ClassLibrary1.Foo;
namespace Algorithums
{
public class Program
{
public static void Draw(float x, float y)
{
// impl
}
public static void Main(string[] args)
{
RegisterWindowFunctionActionAndWindow("Window Name", 450);
Console.WriteLine("Hello World!");
Console.ReadLine();
}
public static void RegisterWindowFunctionActionAndWindow(string WindowName, int order)
{
var jsoType = Type.GetType("ClassLibrary1.Foo,ClassLibrary1");
var jso = Activator.CreateInstance(jsoType);
var mi = typeof(Program).GetMethod("Draw");
var d = Delegate.CreateDelegate(typeof(WindowFunction), mi);
var mi0 = jsoType.GetMethod("Window", new[] { typeof(string), typeof(WindowFunction), typeof(int) });
mi0.Invoke(jso, new object[] { WindowName, d, order });
}
}

error CS0116: A namespace cannot directly contain members such as fields or methods- hand writing coding using notepad

Getting the error on line 16, with the foreach. My professor wont email fast enough and the due date is in a few hours! I think I am missing a list or something. I think the d after the double is incorrect. Any help is appectiated!
using System;
using System.Windows.Forms;
using System.Collections.Generic;
public class Starbucks
{
public static void Main()
{
double[] x = {4.2, 5.7, 3.6, 9.1, 2.7, 8.4 };
}
}
static void MyGenerics(double x)
{
foreach (double d in x)
{
MessageBox.Show(x);
}
}
That's because you have defined the MyGenerics() method outside the class Starbucks. Move it inside the class. Error message is exactly telling the same thing. Your code should look like
using System;
using System.Windows.Forms;
using System.Collections.Generic;
public class Starbucks
{
public static void Main()
{
double[] x = {4.2, 5.7, 3.6, 9.1, 2.7, 8.4 };
MyGenerics(x);
}
static void MyGenerics(double[] xx)
{
foreach (double d in xx)
{
MessageBox.Show(d);
}
}
}
This problem can be caused by bad indentation. For example:
using System;
namespace Interrogacion_1.Model
{
interface IClass
{
public string Name { get; set; }
}
{
Console.WriteLine("HELLO WORLD"); #here error cs0116
}
}
The correct way would be:
using System;
namespace Interrogacion_1.Model
{
interface IClass
{
public string Name { get; set; }
public void Imprimir()
{
Console.WriteLine("HELLO WORLD");
}
}
}

MEF based plugin system can't instance my plugins

I've implemented a very small plugin system based on C# with MEF. The problem is, none of my plugins are instanced. In the Aggregate-Catalog I can see my plugin listed. But, after I'll compose these parts, there isn't my plugin in the plugin list, what I'm doing wrong?
Here's a snippet of my code:
Plugin-Loader:
[ImportMany(typeof(IFetchService))]
private IFetchService[] _pluginList;
private AggregateCatalog _pluginCatalog;
private const string pluginPathKey = "PluginPath";
...
public PluginManager(ApplicationContext context)
{
var dirCatalog = new DirectoryCatalog(ConfigurationManager.AppSettings[pluginPathKey]);
//Here's my plugin listed...
_pluginCatalog = new AggregateCatalog(dirCatalog);
var compositionContainer = new CompositionContainer(_pluginCatalog);
compositionContainer.ComposeParts(this);
}
...
And here, the plugin itself:
[Export(typeof(IFetchService))]
public class MySamplePlugin : IFetchService
{
public MySamplePlugin()
{
Console.WriteLine("Plugin entered");
}
...
}
Tested working sample.
Compile class library with code inside PluginNameSpace namespace and place it to the 'Test' folder which will be inside console app exe folder.
using System;
using System.ComponentModel.Composition;
using System.ComponentModel.Composition.Hosting;
using System.IO;
using System.Reflection;
using ConsoleApplication;
namespace ConsoleApplication
{
public interface IFetchService
{
void Write();
}
class PluginManager
{
[ImportMany(typeof(IFetchService))]
public IFetchService[] PluginList;
public PluginManager()
{
var dirCatalog = new DirectoryCatalog(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location) + "\\Test");
var pluginCatalog = new AggregateCatalog(dirCatalog);
var compositionContainer = new CompositionContainer(pluginCatalog);
compositionContainer.ComposeParts(this);
}
}
class Program
{
static void Main(string[] args)
{
var pluginManager = new PluginManager();
foreach (var fetchService in pluginManager.PluginList)
{
fetchService.Write();
}
Console.ReadKey();
}
}
}
// Separate class library
namespace PluginNameSpace
{
[Export(typeof(IFetchService))]
public class MySamplePlugin : IFetchService
{
public void Write()
{
Console.WriteLine("Plugin entered");
}
}
}

Access C# Enums and Classes from other namespaces in IronPython

I am stuck on what I would think should be a rather basic feature of IronPython integration with C# (this is, of course, a very simplified example). Below is a simple multi-project solution. The first project defines an enum and a class from one namespace
namespace EnumTest
{
public class EnumTest
{
public enum FooEnum
{
FooOne = 101,
FooTwo = 102,
};
public EnumTest(FooEnum f)
{
_f = f;
}
}
}
Then, I have another project which encompasses all of IronPython: the runtime DLLs, the Python modules, and the C# class that runs the python script from a file.
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using IronPython.Hosting;
using Microsoft.Scripting;
using Microsoft.Scripting.Hosting;
namespace IronPythonRunner
{
public class IronPythonRunner
{
public IronPythonRunner()
{
ScriptEngine ironPythonEngine = Python.CreateEngine();
ScriptScope pythonScope = ironPythonEngine.CreateScope();
dynamic scope = pythonScope;
const string script = "c:/temp/try.py";
String scriptDir = Path.GetDirectoryName(script);
String ironPyDir = Path.GetDirectoryName(Assembly.GetEntryAssembly().Location) + "\\IronPythonDistributable\\Lib";
ICollection<String> paths = ironPythonEngine.GetSearchPaths();
paths.Add(scriptDir);
paths.Add(ironPyDir);
ironPythonEngine.SetSearchPaths(paths);
ScriptSource source = ironPythonEngine.CreateScriptSourceFromFile(script);
try
{
source.Execute(pythonScope);
}
catch (Exception e)
{
Debug.WriteLine(e.ToString());
}
finally
{
ironPythonEngine.Runtime.Shutdown();
}
}
}
}
Finally, I have a c# project that is a test GUI for running a python script
using System;
using System.Windows.Forms;
namespace IronPythonNamespaceTest
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
private void button1_Click(object sender, EventArgs e)
{
IronPythonRunner.IronPythonRunner r = new IronPythonRunner.IronPythonRunner();
}
}
}
When I try to run the following python script
print "hello world"
print str(FooEnum.FooOne)
t = EnumTest(FooEnum.FooTwo)
I get the "hello world" output, but then I get a C# IronPython.Runtime.UnboundNameException: name 'FooEnum' is not defined. Which brings me to my question, how should I be accessing the enum and the class from within my python script?
You need to import your assembly:
import clr
clr.AddReference("assembly_name")
from EnumTest import EnumTest
from EnumTest.EnumTest import FooEnum

C#: Access Enum from another class

I know I can put my enum at the Namespace area of a class so everyone can access it being in the same namespace.
// defined in class2
public enum Mode { Selected, New, }
What I want is to access this enum from
public class1
{
var class2 = new class2();
// Set the Mode
class2.Mode = Model.Selected
}
Is this somehow possible without using namespace area?
You can declare an enum outside of a class:
namespace MyNamespace
{
public enum MyEnum
{
Entry1,
Entry2,
}
}
And then you can add using MyNamespace; where it needs to be used.
Aaron's answer is very nice but I believe there is a much better way to do this:
public static class class1
{
public void Run()
{
class2.Mode mode = class2.Mode.Selected;
if (mode == class2.Mode.Selected)
{
// Do something crazy here...
}
}
}
public static class class2
{
public enum Mode
{
Selected,
New
}
}
No point over complicating this. It is a simple task.
All the Best
Chris.
If you are trying to do what is described below it will not work...
public class MyClass1
{
private enum Mode { New, Selected };
public Mode ModeProperty { get; set; }
}
public class MyClass2
{
public MyClass2()
{
var myClass1 = new MyClass1();
//this will not work due to protection level
myClass1.ModeProperty = MyClass1.Mode.
}
}
What you could do however is below, which will work...
public interface IEnums
{
public enum Mode { New, Selected };
}
public class MyClass1
{
public IEnums.Mode ModeProperty { get; set; }
}
public class MyClass2
{
public MyClass2()
{
var myClass1 = new MyClass1();
//this will work
myClass1.ModeProperty = IEnums.Mode.New;
}
}
Yes:
class2.Mode = class2.Mode.Selected
But note that you can't have a nested type defined that has the same name as one of the outer class' members, so this code will not compile. Either the enum or the property will need to be named something else. Your class name and variable name conflict too, making this a bit more complex.
To make this a more generic answer, if you have this:
public class Foo
{
public SomeEnum SomeProperty { get; set; }
public enum SomeEnum {
Hello, World
}
}
Then this code will assign an enum value to the property:
Foo foo = new Foo();
foo.SomeProperty = Foo.SomeEnum.Hello;
I ended up solving my issue by changing it to a namespace accessor, found by utilizing Intellisense. I thought the enum was in the class, not just the namespace. If it was in the class, I would recommend moving it out of the class.
namespace ABC.XYZ.Contracts
{
public class ChangeOrder : BaseEntity, IAuditable
{
...
}
public enum ContractorSignatureType
{
A,
B,
V
}
}
ContractorSignatureType = Contracts.ContractorSignatureType.B,
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace #enum
{
class temp
{
public enum names
{
mohitt,
keval,
Harshal,
nikk
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine((int)temp.names.nikk);
Console.ReadKey();
}
}
}
//by using this you can access the value of enum.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace #enum
{
class temp
{
public enum names
{
mohitt,
keval,
Harshal,
nikk
}
}
class Program
{
static void Main(string[] args)
{
Console.WriteLine(temp.names.nikk);
Console.ReadKey();
}
}
}

Categories

Resources