How to add an extension method to .Net assembly? - c#

I am new to software development and may be I am asking a very silly question but, I am curious to learn more on this thing.
Is it possible to add an extension method to .Net assembly? I want my extension method to work on every project I am working on. Apart from referencing to my own assembly, is there any other way?
If it is not possible, please explain taking some time.
Thanks in advance :)

There's no way of adding methods to an existing assembly.
There's no other way than creating it in your own assembly and referencing that.

Create a new project as a dll (class library)
Add your extention classes/methods to this dll
Reference this dll in your future projects
In response to your comment, you cannot modify the .net framework, only build your own dll's to include methods you wish to share between projects.
The reason you cannot modify the framework is because the code has been compiled already.

You can create extensible method in class but not possible in your reference dll
please check here extensible class method

Is it possible to add an extension method to .Net assembly?
this itself says that you have to create your own methods to extend .Net assembly which are already deployed. The only way to use is define your own methods and include the namespace in the code where you will use these extenssion methods.
sample. of Extenssion methods.
using system;
namespace myNamespace
{
public static class MyExtMethods
{
public static string Foo(this string bar)
{
return bar+ "Some values added. ";
}
}
}
Uses of Extenssion Method.
using system;
using myNamespace;
namespace myNamespace2
{
public class Program
{
public static void Main(string[] args)
{
string str ="Some Value";
Console.WriteLine(str.Foo());
}
}
}

Related

Can I restrict the visibility of C# extension methods to classes in the same assembly?

Say I have these files:
MyCode.cs
namespace MyCodeNamespace
{
public class MyClass
{
//OMITTED
}
internal static class MyExtensions
{
internal static void Foo(this string str)
{
//OMITTED
}
}
}
OtherCode.cs
using MyCodeNamespace;
namespace OtherCodeNamespace
{
//OMITTED
}
The two files are part of the same assembly. Is there any way I can make Foo accessible to MyCode.cs but not to OtherCode.cs? My question is similar to this question:
C# Extension Methods only visible and accessible within one class ("private")
But its accepted answer isn't really what I'm looking for. I want to make an extension method that's only visible to the code I'm working on, and according to the answer to the above question, someone could still access it by adding a "using" statement. Is there a way I can create an extension method that is only visible to my code, and nowhere else, not even by another class in the same assembly?
I ask because the syntax for calling an extension method is handy and would be useful for what I'm working on (otherwise I'd just create a private method instead), but I don't want others to see it and use it from their code in case it doesn't do what they assume it does. And thanks to Visual Studio's intellisense, my extension methods are currently showing up in the list of available methods (along with the option to add the namespace they're in).
There is no such thing as a namespace-limited access modifier in the .NET platform. From the docs
public : Access is not restricted.
protected : Access is limited to the containing class or types derived from the containing class.
Internal : Access is limited to the current assembly.
protected internal: Access is limited to the current assembly or types derived from the containing class.
private : Access is limited to the containing type.
That's all you have to work with. So the answer is no.
Extension methods are just semantic sugar that compile to the same IL as calling the static helpers directly.
MyExtensionMethods.DoSomething(myObject);
myObject.DoSomething();
You cannot restrict it from being called, but you can remove its visibility from Intellisense.
Simply move your extension methods to a different namespace, add a using statement in your MyCode.cs and don't include that namespace in OtherCode.cs
[update]
If you really need to restrict the caller, you could try using reflection to determine and restrict, but this is a bit overkill. Best to simply use a private static helper instead of doing this.
var frame = new System.Diagnostics.StackFrame(1, false);
var method = frame.GetMethod();
var type = method.DeclaringType;
// allow|deny type
I had a similar problem. I did not want the programmer to see my inner extension methods when configuring services in ASP.NET Core.
The solution for me was to add all extension methods to namespace Microsoft.Extensions.DependencyInjection that is used in Startup.cs and the user can see those methods. (As you would always do.)
If I wanted to "hide" something I added the extension method to MyNamespace.Extensions. If the user writes the correct name the helper for add using will show up but by default it won't be listed.
I know this is not a solution but might help someone.
think about similar thing;
c# assembly, friend assembly
will try InternalsVisibleTo;
if your classes is closed maybe will not helpfull but you can try it;

Can I "add" static methods to existing class in the .NET API?

I want to build a Windows Store class library using source code from a regular .NET Framework class library. Ideally, I do not want to modify the original source code files.
In some of the source code files from the .NET Framework library, static members are used from a class that is defined in both the regular .NET Framework API and the .NET for Windows Store apps API, but where only a subset of the .NET Framework members are available for Windows Store.
One specific example is System.IO.Path, where the GetFullPath method is not available for Windows Store apps.
It is fairly straightforward to incorporate a replacement for this method in my Windows Store class library and have the original source code invoke this method instead. My question is, is there any way I can do this without modifying the original source code file?
So far, I have not been able to figure out a satisfactory solution to this problem, but I have solved it for my Windows Store class library by implementing e.g. the Path.GetFullPath(string) method in another namespace:
namespace WindowsStoreLib.System.IO {
public static class Path {
public static string GetFullPath(string path) { ... }
}
}
and then adding a preprocessor directive in the original files:
#if NETFX_CORE
using Path = WindowsStoreLib.System.IO.Path;
#endif
Is there an alternative solution to this issue that does not require modification of the original source code files?
No, you cannot, simply.
When I'm doing cross-platform stuff I tend to write a utility class that has different implementations (via #if) for different platforms - then my core code just calls the utility class.
I've been doing something like this lately with Entity Framework classes since I needed to add a specific output of 2 fields as 1 and it wiped it out from the designer.cs on every update. However they were not static classes or static methods, but should work with same.
Create a new class file with the name of the class you want to extend and use the partial qualifier.
namespace WindowsStoreLib.System.IO {
public partial static class Path {
public static string GetFullPath(string path) { ... }
}
}
As Marc said, the preprocessor directive seems to be the only solution.
But when I read "static class" and "existing class", the first thing coming to my mind is "extension method". What would happen if you created an extension method for Path in the same namespace where your code is?
namespace MyNamespace.WhereMyCodeIs
{
using System.IO;
public static class ExtensionMethods
{
public static string GetFullPath(this Path pathObject, string path)
{
// Implementation
}
}
}
I am really not sure if this would work out but maybe there is a work around we could find around this.

Access to methods and properties in class library with limitation

I have two class library projects: DataAccessLibrary and ServiceLayerLibrary.
ServiceLayerLibrary needs access to the DataAccessLibrary's methods and properties, but other projects must not have access to DataAccessLibrary.
How can I achieve this?
First, you may wonder if you really need to make sure that DataAccessLibrary is accessed correctly by doing compile-time or run-time checks. Maybe stipulating its proper use in coding guidelines and standards is enough -- and then trust the developers to follow these guidelines. Then again, I don't know your situation :-)
Second, you may wonder if it is really necessary to create separate projects. You may just implement DataAccessLibrary as internal classes in the ServiceLayerLibrary, and then they don't get exposed to the outside world.
If you don't want to do that, then you can make DataAccessLibrary's public methods internal and then state visiblity like so:
[assembly: InternalsVisibleTo("ServiceLayerLibrary")]
Whether that is clean or not is up to you. Personally I'm not a fan of such constructs.
Have your members in DataAcceessLibrary internal and make use of friend assemblies so that ServiceLibrary may access them.
The internal keyword (in C#) gives access to other classes within the same assembly. Friend is the equivalent keyword in VB.Net. However, if you want another assembly to have access to another assembly’s “internal” stuff (in C#), then you can use the method from the web link below called “Friend Assemblies” where it exposes one assembly’s “internal” stuff to another assembly. Nowhere in this process do you actually use a keyword friend or friendly in C#. It is simply what they have called this relationship where you say [assembly:InternalsVisibleTo("MyAssembly")]. This is useful in situations where you have one assembly that utilizes functionality from another assembly that you do not want to make public. You can also use this technique with a strongly-named assembly like so [assembly: InternalsVisibleTo("MyAssembly, PublicKey=xXxXx")].
Example:
using System.Runtime.CompilerServices;
using System;
[assembly: InternalsVisibleTo("ServiceLibrary")]
// The class is internal by default.
class FriendClass
{
public void Test()
{
Console.WriteLine("Sample Class");
}
}
// Public class that has an internal method.
public class ClassWithFriendMethod
{
internal void Test()
{
Console.WriteLine("Sample Method");
}
}
You may also use an alternative signing approach which might be better if you need public members in your DataAccessLibrary. It can be achieved by using LinkCommand with StrongNameIdentityPermission ( see http://www.codeproject.com/Articles/339909/Limiting-the-accessibility-Another-way-of-Friend-A ).

C# "linking" classes

I'm starting a simple C# console solution via Mono on Mac OS X.
I have a Main.cs file for starters, but I want to create a separate class and be able to access object of that class from my Main.cs file.
How can I access that class from the Main.cs file?
Say my class name was Math.
In my Main.cs file, can I create a new object like so:
Math calculator = new Math()
Without referencing the class in the Main.cs file in any way?
Or, do I have to use some sort of import statement/directive?
You need a using statement if your Main and Math are in different name spaces, otherwise it just works. Below is an example. The using System brings in the library that contains the Console class, but no using is required to use the Math class.
Program.cs:
using System;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
Math caclulator = new Math();
Console.WriteLine(caclulator.Add(1, 2));
}
}
}
Math.cs:
namespace ConsoleApplication1
{
class Math
{
public int Add(int x, int y)
{
return x + y;
}
}
}
There are two scenarios here. Either this class is in a separate dll (class library project), or under the same project. To reference within the same project not additional work is needed, other than referencing it with the correct namespace (as mentioned in other posts).
In the case of a separate dll, you need to add a refence to the project in the project definition. Most default projects come with a reference to System.dll and other related libraries. It is recommended to name your dll's based on what namespaces are defined within it. If you have classes like Foo.Mathematics.IntMath, Foo.Mathematics.DblMath then I suggest you name it Foo.Mathematics.dll.
When I was where you are, I picked up .NET Framework Essentials from O'Reilly and it had answers to all my questions at the time.

How do I work with multiple files and C# libraries in F#?

I have a C# library with the following Namespace/Class:
namespace Helper
{
public static class Util
{
/*static methods*/
}
}
I have referenced said library in a F# project and when I try to call one of the methods I get:
error FS0039: The namespace or module 'Helper' is not defined.
This is an example of the method call not working:
#light
let a = Seq.skip 1000 (Helper.Util.GetPrimes 200000);;
Am I missing something obvious? Using open Helper doesn't work either, and the weird thing is that IntelliSense does work, it lists every method in the Util class.
Also, what is the standard practice for calling functions in some of my files from other files in the same project? I don't wanna create full objects just to access a few functions.
Regarding multiple files, see the first portion of "Using multiple F# source files, and a useful debugging technique", as well as the final portion of "Sneak peeks into the F# project system, part three". The former discusses how top-level code in a file implicitly goes in a module of the same name as the filename, whereas the latter discusses how to order files in the project (since you can only see stuff declared above/before you).
What does your GetPrimes method look like? It work for me...
I have a solution with a C# library including this code:
namespace Scratch
{
public static class Util
{
public static IEnumerable<int> GetNumbers(int upto)
{
int i = 0;
while (i++<upto) yield return i;
}
}
}
And calling it from a F# project that references the C# project like this:
#light
let p = Seq.skip 1000 ( Scratch.Util.GetNumbers 2000000);;

Categories

Resources