I have the following situation:
A project MyCompany.MyProject.Domain which contains my domain model, and partial classes (such as Contact).
I want to 'extend' (by partial class, not extension method) my Contact class with a property Slug which will give me a simple URL friendly text representation of first and last name.
I have a string extension method ToSlug() in my Utility project MyCompany.MyProject.Utilities which does exactly what I want in 2).
The problem: My Utility project is already referencing my Domain project which means that I can't get the Domain project to see the Utility project's ToSlug() method without causing circular reference.
I'm not keen on creating another project to solve this, and I really want to keep the Slug logic shared.
How can I solve this?
Your Utility project referencing your MyCompany.MyProject.Domain seems like a bit of a code smell. I'm assuming here that these are utilities that specifically work on domain objects--if that's the case, then why don't you include MyCompany.MyProject.Utilities within your Domain project (naturally, modifying the namespace accordingly)?
In any case, the normal way to break these kinds of dependencies is to abstract what is required by one project into a set of interfaces, and encapsulate those in a separate assembly. Before doing that though, make sure that what you're doing conceptually is the right thing.
In your particular situation though, consider introducing an interface, viz., INameHolder:
public interface INameHolder
{
string FirstName { get; set; }
string LastName { get; set; }
}
Then Contact implements INameHolder. INameHolder exists in another assembly, let's call it MyCompany.MyProject.Domain.Interfaces.
Then your Utilities project references Interfaces (not Domain) and so does Domain, but Interfaces doesn't reference anything--the circular reference is broken.
copy ToSlug method to Domain project and Delegate Utility's ToSlug call to this new method
If you cannot share the domain (probably right) and it must consume the logic from a shared library then then you really have to introduce a another assembly.
Or you could load the logic at runtime in the domain by reflection in the domain to access the dependent library. Its not hard just breaks compile time checking.
If you're sure about keeping the code in the utility DLL (Eric's answer seems smart to me), then you could create an interface in your utility project, pass that interface as a parameter to your ToSlug method and then have your domain object implement the interface.
Related
I have an abstract class compiled into a DLL (let's call it BaseClass.dll) which serves as a base for other classes to inherit from. These other classes are also compiled into DLL's (let's call one of them InheritedClass.dll) which can be used as plugins for my main application which can call the same methods in each plugin as the abstract class forces them to implement.
However, there's some functionality which will be common to all the plugins and so I would prefer if I could implement those in the base class. This cuts down on redundancy and also eliminates the possibility of whoever writes the plugin to make mistakes when implementing that functionality.
One such example is a piece of code that requires the name of the compiled DLL file. A method that would've worked could look like this:
public string GetName()
{
return System.IO.Path.GetFileName(System.Reflection.Assembly.GetExecutingAssembly().CodeBase);
}
The problem is that GetExecutingAssembly() returns the assembly for the code that is currently running, not the assembly into which it has been compiled. So, if I put the above function in BaseClass, it returns (BaseClass.cs), regardless of the name of the DLL that it is compiled into. This means that I have to put it in InheritedClass and can't put it in BaseClass. As explained above, I'd like to avoid that as I don't want to labour the developer of the plugins with this bit of common code and I don't want to rely on these third party developers to get it right.
Is this even possible? Is there a way I can get the name of the DLL which inherited from this base class through code that sits in the base class?
GetType always returns the actual type of an object, so you can use that to find out what type you actually are, then chase from there to the assembly:
public string GetName()
{
return System.IO.Path.GetFileName(GetType().Assembly.CodeBase);
}
Hopefully you'll come up with a better name for this method later. GetName is horribly vague.
I’m a C++ guy which has to work with some C# projects hence I have question. Having two projects placed on different svn servers I need them to share interface classes. How it should be solved in C#.
For example I have cs file which have interface and class used to pass data to the interface i.e.
Public Class data
{
public int a;
public int b;
}
Public Interface Ifoo
{
int foo(data);
}
This interface is implemented in ProjectA and used by ProjectB.
I want to be able to chose implementation of the interface so that in tests of ProjectB I will use special implementation of Ifoo interface.Chosing different dll using :
Assembly assembly = Assembly.LoadFrom(asm_name);
fooer = assembly.CreateInstance(class_name) as Ifoo;
Where I should place Ifoo interface?
I thought it should be placed in ProjectA svn repo (as ProjectA is owner of the interface) and then checkout it as an external with checkout of ProjectB .
Can you tell me what is the rule of thumb in such case?
BR
Krzysztof
First of all, whatever you decide to put your interface and asspciated data class (project A or project B svn or a new one), the first (and quite ovious) recomendation is that you put them together on its own library (DLL), without any dependency on other objects, so that becomes easy to share it across different projects.
To use it on a different project (do not matter if on another svn repository or not), you will have to give to that project physical access to this interface/data class. Being on its own dll and without the constraint of requiring other objects, it's a simple matter of add a reference of the library in the project.
With local copies of both projects, you don't need to copy the library itself into the other project.
In any case, you have to think well of your interface and data, so that you do not contantly make changes to them, in order to avoid having problems of compatibility between the projects. If you need to "add" something to the interface because of new features, create a new interface instead (and put it on other DLL). This way you will maintain compatibility with other projects that do not implement the new features.
If the data associated with the interface is so specific that any class implementing this interface will be used ONLY BY project A, so, the obvious place to put the DLL is into the project A. Usually this is the case when a software has the aability to use plugins. The interfaces are in a dll that can be "public" provided to plugin developers that do not have access to the main project itself. This is so simple as to make the DLL available to download. Beijng the SAME dll used on both main project and plugins, there will be no problems (than the reason to not change it).
But if your interface is more "generic" and is used to create something like a framework, where different projects (not related/not dependent) can use it alone, than, the suggestion to separete it in a third project (with its own svn) is more interesting. Using good polices regarding the development of this interface, will be less problematic to mantain the framework.
In the comments you said you can relate the "interface" to the project A, but if you can use it in project B without project A being involved, you can relate the interface to project B as well, and so, the option of moving the interface/associated data to a separetely project is preferable.
In any case, the underline implementation is irrelevant, as the main reason why we use interfaces in C# is exactly to be able to use an object in a "generic way" whithout (necessarily) having to care about how it is implemented.
We have code that is called by an external framework, ARDEN. Short of a comment (easily overlooked), how can I effectively notify developers of tie in's to this framework? Specifically, a tie in couples the CLASS, NAMESPACE and METHOD to said framework.
namespace MyCompany//changing namespace for this class is NOT SAFE
{
public class MyClass//changing class name is NOT SAFE
{
[TiedToArdenAttribute]//maybe an attribute?
public void MethodCalledByArden() {}//adding params, changing name is NOT SAFE
public void NotCalledByArden() {}//changing this method signature, name, params is OK
}
}
Under normal circumstances, for example when I change the name of MyClass in an assembly via visual studio I can't compile without fixing the references to said class. If the namespace, classname or method name changes...there should be a warning that says "best fix Arden to deal with this change". I considered an Error, but since there's no way to verify Arden is fixed I don't believe that will work.
Is there a way to achieve a similar result for this external framework?
I think whatever you do can be undone by other developers - they can rename class, remove comments, remove attributes.
Try to move this class to separate library instead. And in your project add reference to compiled assembly. That will make class name fixed in your project.
If others are using the code, it is best to talk in terms of contracts and not class instances via interfaces. By allowing the consumer to use an Interface will dictate the primary changes such as property changes...but things like internal class name changes will not affect a consumer. Plus you can version your classes, while working on a new class, the old class could still be used by the consumer until the factory internally releases it, without the consumer knowing that V2 of the class is being used.
As the Title says, I've got a multi-project solution.
I've got a "core" project that is loaded with most of the other projects.
So my question is this, I have a few utility functions such as FormatPhoneNumber(..) that I would like to be able to access in the following manner from anywhere.
(in Project_B which depends on Core)
string str = FormatPhoneNumber(inputString);
At worst, I suppose I could live with a qualifier of some sort:
string str = util.FormatPhoneNumber(inputString);
The best way of doing this is to create a dll project (maybe called something like "CommonCode"?), that you can then reference this dll from all of your other projects and access the classes and methods therein.
You will have to have some sort of "qualifier" (as you call it) somewhere, but to reduce the impact use the using statement at the top of each file, e.g.
using util;
If you really must have such utility functions (you know, you shouldn't, but sometimes it's the best/easiest solution), I suggest having them either in the Core (assuming that every single project is dependent on the Core anyway), or in a separate utility assembly. If you don't want to have a separate assembly lying around, consider using ILMerge.
The qualifier should be no problem at all. I suggest not putting unrelated function into an Utils class, but rather use e.g. a Formatting class for all formatting functions. On the other hand, as s_ruchit in the meantime suggested, extension methods (e.g. for the string class) might come in handy as well.
(Did I mention that this §%$& MarkDown editor does not allow typing an [at] symbol on a German keyboard layout, because it instead creates a blockquote? Sigh.)
Try creating your own util library.
Create a Class Library project and put your util classes in there.
I myself try to adhere a naming convention like [companyName].Util.[subdomain]
Your example would probably fit in my [CompanyName].Utils.StringHelpers
You would then create a static class StringHelper with a static method FormatPhoneNumber.
You will see that these personal libraries quickly grow bigger. By grouping them you don't have to load all your code if you only need a subset of functions.
Use an extension method to make it easier to call the method without using the class name.
public static class Util {
public static string FormatPhoneNumber(this string input) {
:
}
}
The method will now appear on every string object. You do not need to know which class it comes from. However, if the extension class is declared in another namespace, you must still import the namespace.
string formattedString = inputString.FormatPhoneNumber();
If you are using C# 3.0, you can bind them all into one single static class use them as Extension Methods.
There are no global functions in .NET, so you will have to put your utility functions into a class. You can make the methods static, so you can call them without having to instantiate the utility class:
public class Utility
{
public static string FormatPhoneNumber(string input)
{
...
}
}
// usage:
string output = Utility.FormatPhoneNumber(input);
Put these methods into your core library or a separate utility library that can be used (referenced) by all other libraries and applications.
You need to put the functions in static classes. You cannot avoid the qualification (there are no global functions in C#):
<%= Formatters.PhoneNumber(rawData) %>
The utility functions should be grouped as per normal methods: similar methods go together, unrelated methods should go into different classes (event with static classes aim for low coupling and high cohesion).
The assembly each belongs in should be obvious: formatting functions only used by the presentation layer (ASP.NET project itself) belong there. Truly common functions could go into core.
If the function you are implementing can only be used in context of your application, i would recommend you to place it into the Core assembly (under a separate namespace like "Utils" for example) or a new DLL library of your application solution.
Only if the function can be used across multiple projects it makes sense to create a utility library. But always keep in mind that a utility library only make sense if it's maintained regularly.
If you want all code to access these methods then go with extension methods, otherwise I would go with Util class in core assembly.
FWIW, if you follow a more formalised namespace as boris sugguests (recommended to avoid conflicts) you can abbreviate with the using keyword:
using Util = [CompanyName].Utils.StringHelpers;
I tend to follow the DRY principle and create an alias as soon as I need it more than once.
In C#, I am developing several Windows Services which have some standard functionality so I have put all this common functionality into a separate referenced utility project.
I have a situation where I need to create instances of business classes which reside in my Windows Service project from the utility project using Activator.CreateInstance.
My utility project is aware of the namespace and the class name for the Type.GetType call but the type is always null and when I think about it, it won’t be able to get the type from the project it’s referenced to, or can it?
In short:
Project A references Utility Project.
Utility Project wants to create class from Project A, its aware of the namespace and class name.
Is there a Design Pattern or an approach that I should be following to achieve this functionality? Or does this look like a no, no and I should be refactoring?
Thanks for looking
You can solve the circular reference problem using reflection, as Jon pointed out, but I suggest rethinking the design and refactoring it. Two suggestions.
Use interfaces to decuple A and B. (prefered solution)
Move the part needed by A and B into C and reference only C from A and B.
You need to specify the fully-qualified assembly name (including version etc, if it's strongly named) if you want Type.GetType to find a type which isn't in either mscorlib or the calling assembly.
For example:
// Prints nothing
Console.WriteLine(Type.GetType("System.Linq.Enumerable"));
// Prints the type name (i.e. it finds it)
Console.WriteLine(Type.GetType("System.Linq.Enumerable, System.Core, "
+ "Version=3.5.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"));
Alternatively, can you make this a generic method in the utility project, and get the caller to specify the type as a type argument?
You could look into dependency injection/ioc containers.
For example create an interface in the utility library and implement that in a specific class in the windows service. Then pass an instance to the utility class. This way the utility library doesn't have know anything about the windows service.
Sounds like a circular reference problem! You may need to refactor!