Why cant I expose an implemented interface method? - c#

I've been trying out some n-tier architecture and im really wondering why this code wont compile...
It says the modifier public is not valid for this item. But why not? I need to be able to access the item IRepository.AddString() from a BLL object but it just wont let me make it public....
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace ConsoleApplication1
{
class Program
{
static void Main(string[] args)
{
BLL myBLL = new BLL();
}
}
interface IRepository<T>
{
void AddString();
}
interface IStringRepo : IRepository<string>
{
List<string> GetStrings();
}
public class BLL : IStringRepo
{
public List<string> FilterStrings()
{
return new List<string>() { "Hello", "World" };
}
public List<string> IStringRepo.GetStrings()
{
throw new NotImplementedException();
}
public void IRepository<string>.AddString()
{
throw new NotImplementedException();
}
}
}

That's an explicitly-implemented member, which is always private.
Remove IStringRepo. from the declaration to create a normal public member that also implements the interface.

Explicitly implemented interfaces cannot use visibility modifiers.
public List<string> IStringRepo.GetStrings()
should be:
public List<string> GetStrings()

Related

Allowing extending classes only for specific classes - c#

Is it possible to allow only specific classes to extend the class?
Suppose I have created class A but I want to allow to inherit this class only for class B and class C.
means class A should not allow extending for class.
is it possible to implement in that way in c#? using reflection or any other way?
You can only do this by defining the other classes in the different assembly and declare the constructor of the base class as internal.
If you want to do this at compile time, but don't want to use the internal modifier (for example, if this is in a package), what you can do is to create your own Roslyn analyzer.
Here's a very basic example of how you could achieve this for compile-time errors:
[DiagnosticAnalyzer(LanguageNames.CSharp)]
public class PreventInheritanceAnalyzer : DiagnosticAnalyzer
{
public const string DiagnosticId = "PreventInheritanceAnalyzer";
private static readonly string Title = "Title";
private static readonly string MessageFormat = "Message format";
private static readonly string Description = "Description";
private const string Category = "Naming";
private static readonly DiagnosticDescriptor Rule = new DiagnosticDescriptor(DiagnosticId, Title, MessageFormat, Category,
DiagnosticSeverity.Error, isEnabledByDefault: true, description: Description);
private static HashSet<string> _acceptedClasses;
public override ImmutableArray<DiagnosticDescriptor> SupportedDiagnostics => ImmutableArray.Create(Rule);
public PreventInheritanceAnalyzer()
{
_acceptedClasses = new HashSet<string>(new[] { "MyNumberOneClass", "MyOtherSpecialClass" });
}
public override void Initialize(AnalysisContext context)
{
context.EnableConcurrentExecution();
context.ConfigureGeneratedCodeAnalysis(GeneratedCodeAnalysisFlags.Analyze | GeneratedCodeAnalysisFlags.ReportDiagnostics);
context.RegisterSymbolAction(AnalyzeSymbol, SymbolKind.NamedType);
}
private static void AnalyzeSymbol(SymbolAnalysisContext context)
{
var namedTypeSymbol = (INamedTypeSymbol)context.Symbol;
// if it's not a class, we are not interested
if (namedTypeSymbol.TypeKind != TypeKind.Class)
{
return;
}
// if it doesn't inherit from our special class, we are not interested,
// and if it does but its name is one we allow, we are still not interested
if (namedTypeSymbol.BaseType == null || namedTypeSymbol.BaseType.Name != "MySpecialClass" || _acceptedClasses.Contains(namedTypeSymbol.Name))
{
return;
}
// otherwise, this is a bad class, report the error
var diagnostic = Diagnostic.Create(Rule, namedTypeSymbol.Locations[0], namedTypeSymbol.Name);
context.ReportDiagnostic(diagnostic);
}
}
And this is a very basic unit test, to demonstrate that the above works:
[TestMethod]
public void TestMethod2()
{
var test = #"
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Diagnostics;
namespace ConsoleApplication1
{
public class MySpecialClass { }
public class MyNumberOneClass : MySpecialClass { }
public class MySuperSpecialClass : MySpecialClass { }
}";
VerifyCSharpDiagnostic(test, new[]
{
new DiagnosticResult
{
Id = "PreventInheritanceAnalyzer",
Locations = new[] { new DiagnosticResultLocation("Test0.cs", 13, 18) },
Message = "Message format",
Severity = DiagnosticSeverity.Error
}
});
}
One could check this.GetType() in the constructor of the base type (remember: GetType() returns the concrete type) and throw if it’s not an “approved type”.. however, such is a run-time check outside of the type-system.
protected BaseTypeCtor() {
if (GetType() != typeof(OnlyAllowedSubtype))
throw new Exception("Nope! Not allowed to subclass this type!");
}
Visibility restrictions — that which can cause compile-time errors — can generally only be controlled at the assembly level or for all subtypes.
If the types as indeed in different assemblies, marking the base constructor internal may be sufficient and is often cleaner. Unfortunately, C# currently cannot specify “internal and protected” as a modifier.

Interface member with "this" keyword

While going through our client's code, I came across below interface in C#, which is having a member with "this" keyword.
public interface ISettings
{
string this[string key] { get; }
}
I am not aware of any such pattern or practice where interface member name starts with "this". To understand more, I checked the implementation of this interface, however still not able to figure out its purpose.
internal class SettingsManager : ISettings
{
public string this[string key]
{
get { return ConfigurationManager.AppSettings[key]; }
}
...
...
}
And here is the caller code:
public static class Utility
{
public static ISettings Handler { get; set; }
public static string Get(string key, string defaultValue)
{
var result = Handler[key];
return Is.EmptyString(result) ? defaultValue : result;
}
}
Unfortunately, I am not able to debug this code to see the things live. But very curious about it. If the implemented code is finally returning a string, then what is the use of "this" keyword out there?
It enables you to do things like:
SettingsManager settings = new SettingsManager();
var setting = settings["my setting"];
A common use is with the List<T> class.
It has the definition:
public class List<T> : IList<T>, ICollection<T>, IList, ICollection, IReadOnlyList<T>, IReadOnlyCollection<T>, IEnumerable<T>, IEnumerable
{
// ....
public T this[int index] { get; set; }
// ....
}
This allows you to 'index' the internal values in a similar way to an array.
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
namespace test
{
static class Program
{
static void Main()
{
List<string> myStrings = new List<string>();
myStrings.Add("abc");
myStrings.Add("def");
Console.WriteLine(myStrings[0]); // outputs: "abc"
Console.WriteLine(myStrings[1]); // outputs: "def"
Console.Read();
}
}
}
They are indexers, allowing to access your class like an array, in the example your provided you see the usage in this line:
var result = Handler[key];

extending classes that must be used in an interface

I have created an interface as shown below. The DTO object is a complex value object with 3 parameters.
public interface IOperation
{
DTO Operate(DTO ArchiveAndPurgeDTO);
}
I need people that impliment this interface to be able to inherit from the original Value object and extend it where required.
My assumption was that they could simply inherit the DTO object, add (for example) another property and use it in the same class that impliments this interface.
When I try to use the extended value object, Visual Studio complains that I am no longer implimenting the interface.
How can I impliment this functionality.
Thanks in advance for any ideas, and/or suggestions.
Gineer
Edit:
DTO Code:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Company.ArchiveAndPurge
{
public class DTO
{
public DTO(String FriendlyID)
{
friendlyId = FriendlyID;
}
private String friendlyId = String.Empty;
public String FriendlyId
{
get { return friendlyId; }
set { friendlyId = value; }
}
private String internalId = String.Empty;
public String InternalyId
{
get { return internalId; }
set { internalId = value; }
}
private Boolean archivedSuccessfully = false;
public Boolean ArchivedSuccessfully
{
get { return archivedSuccessfully; }
set { archivedSuccessfully = value; }
}
}
}
Extended DTO:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Company.MSO.ArchiveAndPurge
{
public class DTO: Company.ArchiveAndPurge.DTO
{
private Boolean requiresArchiving = true;
public Boolean RequiresArchiving
{
get { return requiresArchiving; }
set { requiresArchiving = value; }
}
}
}
Interface Implementation where VS Complains:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Company.ArchiveAndPurge.Contracts;
using Company.ArchiveAndPurge;
namespace Company.MSO.ArchiveAndPurge
{
public class ResolveFriendlyId: IOperation
{
#region IOperation Members
public DTO Operate(DTO ArchiveAndPurgeDTO)
{
ArchiveAndPurgeDTO.InternalyId = ArchiveAndPurgeDTO.FriendlyId;
return ArchiveAndPurgeDTO;
}
#endregion
}
}
As I understand it, you probably had something like:
public class ExtendedOperation : IOperation
{
public ExtendedDTO Operate(ExtendedDTO dto)
{
...
}
}
That doesn't work in two ways:
You can't change the return type when implementing an interface method
You can't change the parameter list when implementing an interface
In particular, you wouldn't be implementing IOperation in a way which would be compatible with code like this:
IOperation operation = new ExtendedOperation();
operation.Operate(new DTO());
I suspect you might want to make the interface generic:
public interface IOperation<T> where T : DTO
{
T Operate(T dto);
}
Use Generics:
public interface IOperation<T> where T : DTO
{
T Operate(T ArchiveAndPurgeDTO);
}

Determine type derivation from generic type

I have the following utility routine which determine whether a type derives from a specific type:
private static bool DerivesFrom(Type rType, Type rDerivedType)
{
while ((rType != null) && ((rType != rDerivedType)))
rType = rType.BaseType;
return (rType == rDerivedType);
}
(actually I don't know whether there is a more convenient way to test the derivation...)
The problem is I want to determine whether a type derives from a generic type, but without specify the generic arguments.
For example I can write:
DerivesFrom(typeof(ClassA), typeof(MyGenericClass<ClassB>))
but what I need is the following
DerivesFrom(typeof(ClassA), typeof(MyGenericClass))
How can I achieve it?
Based on the example of Darin Miritrov, this is a sample application:
using System;
using System.Collections.Generic;
using System.Reflection;
using System.Text;
namespace ConsoleApplication1
{
public class MyGenericClass<T> { }
public class ClassB {}
public class ClassA : MyGenericClass<ClassB> { }
class Program
{
static void Main()
{
bool result = DerivesFrom(typeof(ClassA), typeof(MyGenericClass<>));
Console.WriteLine(result); // prints **false**
}
private static bool DerivesFrom(Type rType, Type rDerivedType)
{
return rType.IsSubclassOf(rDerivedType);
}
}
}
You could leave the generic parameter open:
DerivesFrom(typeof(ClassA), typeof(MyGenericClass<>));
should work. Example:
public class ClassA { }
public class MyGenericClass<T>: ClassA { }
class Program
{
static void Main()
{
var result = DerivesFrom(typeof(MyGenericClass<>), typeof(ClassA));
Console.WriteLine(result); // prints True
}
private static bool DerivesFrom(Type rType, Type rDerivedType)
{
return rType.IsSubclassOf(rDerivedType);
}
}
Also notice the usage of IsSubClassOf method which should simplify your DerivesFrom method and kind of defeat its purpose. There's also the IsAssignableFrom method you may take a look at.

Unable to Get data from DA layer. What to do?

While dividing my C# application in layers, I have solved the problem of circular dependency among layers in the following way:
using System;
using System.Collections.Generic;
using System.Text;
using SolvingCircularDependency.Common;
using SolvingCircularDependency.DA;
namespace SolvingCircularDependency.BO
{
public class MyClass : IPersistent
{
private string _message;
public string Message
{
get { return _message; }
set { _message = value; }
}
public bool Save()
{
return MyClassDA.Save(this);
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
namespace SolvingCircularDependency.Common
{
public interface IPersistent
{
bool Save();
string Message { get;}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using SolvingCircularDependency.Common;
namespace SolvingCircularDependency.DA
{
public class MyClassDA
{
public static bool Save(IPersistent obj)
{
Console.WriteLine(obj.Message);
return true;
}
}
}
using System;
using System.Collections.Generic;
using System.Text;
using SolvingCircularDependency.BO;
namespace SolvingCircularDependency.UI
{
class Program
{
static void Main(string[] args)
{
MyClass myobj = new MyClass();
myobj.Message = "Goodbye Circular Dependency!";
myobj.Save();
Console.ReadLine();
}
}
}
Please take a look at the class MyClassDA in the DA layer and the assembly itself.
How can a MyDA.Get() method return objects of type MyClass when the Data Access layer doesn't know about the MyClass type.
If this design is not efficient, How can I change/modify it?
As far as I can understand you have a bidirectional relationship between your DA and Business layer.
To solve this problem I suggest that you should have 3 layers instead of two. I mean you should have a Model layer that simply model the DB objects ,then you can derive from model classes in your Business layer and add other behaviors like Save method.
Here's what I mean:
//Model Layer
public class UserModel
{
public virtual string Firstname{get;set;}
}
//DataAccess Layer
public class UserDao
{
List<UserModel> GetAll();
}
//BusinessLayer
public class UserDomainModel:UserModel
{
public UserDomainModel(UserModel user,UserDao dao)
{
_user=user;
_dao=dao;
}
public override string FirstName
{
get
{
return _user.FirstName;
}
set
{
_user.FirstName=value;
}
public void Save()
{
_dao.Save(_user);
}
}
}
I'm using a decorator to combine User and UserDao as a domain model object.
One of the reasons people do Persistance Ignorant objects (POCO) is to avoid such a scenario. There is simply no way for the data access layer to have a reference to a class that it doesn't know about - it is much better to have the class not know about the data access.
The only way you can really do this is to implement Get() on User instead of on UserDA. You can do something like this:
public class User {
IGetFromPresistance<User> _userFetcher;
public static IList<User> GetMatching(Specification<User> spec) {
var values = _userFetcher.Find(spec); //Returns a DataRow or IDictionary<string, object>
return new User() {
PhoneNumber = new PhoneNumber(values["phone"].ToString()),
Name = values["name"].ToString(),
};
}
}

Categories