Restricting class method access to one other class - c#

Greetings.
I have two classes, 'Database' and 'Group.' I want to be able to create instances of 'Group' and call methods on those instances from within 'Database' and to be able to distribute 'Group' instance references publicly. However, I do not want to provide public access to the constructor or other methods in 'Group.'
I originally thought that I could achieve this access restriction by making 'Group' a private inner class of 'Database,' but I discovered that I couldn't publicly distribute references to 'Group' if it was private. Also, my attempts at making 'Group' a public inner class failed, because if its methods were all private, 'Database' couldn't access them, and if they were public, access was possible beyond 'Database.'
I am looking for a best-practice technique for solving or circumventing this problem. Maybe I missed a necessary keyword somewhere? Nothing I have found thus far in my research has indicated that C# permits this granularity of control. I found a messy way to get around the problem, as I've provided below in code. Its essence is this: before every call in 'Database' to a method in 'Group,' set a field in 'Database,' publicly readable but only privately settable, that 'Group''s methods all check in their creating instances of 'Database' before performing their intended operations. When reading the field (via a public method in 'Database,') the field is reset, preventing any further method calls on 'Group' until 'Database' sets the field again.
public class Database {
// Field; true if Database has just authorized a method call to a %Group.
private bool group_isNextCallAuthorized = false;
// Invoked before every method call to a %Group.
private void Group_AuthorizeNextCall() {
group_isNextCallAuthorized = true;
}
// Method, ordinarily called from %Group, that checks its creating %Database
// that the %Database itself authorized the method call on the %Group. It
// automatically resets the authorization to false to prepare for the next,
// perhaps unauthorized, method call.
public bool Group_IsNextCallAuthorized() {
bool previousValue = group_isNextCallAuthorized;
group_isNextCallAuthorized = false;
return previousValue;
}
// Constructor; creates a demo %Group.
public Database() {
// Create a %Group, first authorizing the action.
Group_AuthorizeNextCall();
Group group = Group.Create(this);
// Call some method on the group
Group_AuthorizeNextCall();
group.SomeGroupMethod();
}
}
public class Group {
// Field; refers to the %Database that created this %Group instance.
private Database db;
// Generates an instance of %Group, requiring the creating %Database as an
// argument. After checking that the %Database %db isn't null, it verifies
// that %db actually requests and authorized this %Group's creation via the
// %Group_IsNextCallAuthorized(.) method provided by %Database.
public static Group Create(Database db) {
// It will not create a dud instance of %Group; it will throw an exception
// instead.
if ((db == null) || !db.Group_IsNextCallAuthorized())
throw new System.Exception("Unauthorized access.");
return new Group(db);
}
// This constructor is referenced internally by static %Create(.) as above.
private Group(Database db) {
this.db = db;
}
// This is an arbitrary method showing that it must check that the %Database
// that created this %Group authorized this method call before it will
// perform its intended function.
public void SomeGroupMethod() {
if (!db.Group_IsNextCallAuthorized())
throw new System.Exception("Unauthorized access.");
// intended functionality...
}
}

One option would be to expose an interface IGroup to the outside parts of your code. This interface would only have getters on the properties, whatever methods you want accessible, etc. Then Database would operate on the Group class, having full access to all properties/methods, and returning IGroup

You can use nested class approach. Probably not the most eligant one since tightly coupled but will do the trick.
public class DataBase
{
private class Group
{
private Group() {}
}
private Group group = null;
public DataBase()
{
this.group = new Group();
}
public Group
{
get
{
return this.group;
}
}

To express this visibility using C# access rules, you need to reverse the class nesting: make Database a nested class inside Group, so it can access the private bits of Group.

Related

C# Access a static method that is hidden by a local property

I'm sure this must have been asked already, but I can't seem to find the answer. I need to know how to access a static method, when the class it is defined within has been hidden by an instance method with the same name.
I have a class which exposes a static method as follows:
public class Plan
{
public static Plan Generate(Project project)
{
var plan = new Plan();
// ...
return plan;
}
}
I then have another class which contains a method called "Plan", from which I want to call the static method mentioned above:
public ActionResult Plan(int id)
{
// ...
var plan = Plan.Generate(project);
// ...
}
The problem is that the class name 'Plan' is hidden by the method name, so I cannot call the static method directly.
Qualify your access to the Plan type with the type's name. For example:
YourNamespace.Plan.Generate
That said, static methods are bad mkay. Make yourself an IPlanFactory, bind PlanFactory to it and let dependency injection do the rest (assuming you're using constructor injection and not that hairbrained dependency resolver stuff). Now it's unambigiously _planFactory.Generate(...) and you've just increased testability. Give yourself a raise!

C# Activator.CreateInstance generic instance getting lost

FYI: the verbose preamble is to help explain why I am using Activator.CreateInstance. I have a number of entities (objects corresponding to database column information) that are "contained" in multiple databases, each of which has a different table/column setup. So I am able to retrieve an entity from each database, but the way I retrieve it is different per database. The database type is not known till runtime and could vary throughout execution. I have created the following setup:
First define the query operations each entity should support and each entity reader should support these operations.
public abstract class Operations<T> {
public delegate T findDelegate(int id);
public findDelegate find;
}
// there are many of these N=1,2,..., but here is one
// use abstract class since implementation of queries should be done by handlers
public class EntityNReader : Operations<EntityN> {
public Reader();
}
Define an interface for "Handler" classes, i.e. these classes implement the query operations listed above.
public interface IHandler<T> {
public string find(int id);
}
// there are many of these N,M=1,2..., but here is one
// use of interface is to force handlers to implement all query types
public class EntityNHandlerForDbTypeM : IHandler<EntityN> {
public string find(int id) {/*whatever*/}
}
This allows the developers to create a single class for handling EntityN query operations for DbTypeM. Now, create a Database class that contains the reader objects and binds the handler methods to the reader delegates.
public class Database {
// there are many of these, but here is one
public EntityNReader EntitiesN;
public Database(string dbType) {
// this is called for each EntityNReader
bindHandlers<Reader, TypeN>(MyReader, dbType);
// ...
// nullreferenceexception
EntitiesN.find(0);
}
// this is a factory that also performs late binding
private void bindHandlers<T,K>(T reader, string dbTypeM)
where T: Operations<K>, new()
{
// create instance of EntityNReader
r = (T)Activator.CreateInstance(typeof(T));
// r != null
// create instance of handler
IHandler<K> h = (IHandler<K>)(Activator.CreateInstance(
Type.GetType("namespace.to.EntityNHandlerForDbTypeM"),
new object[] { this }
));
// bind delegates
r.find = h.find;
}
}
As you can see in Databases constructor, the way the code is written now, I get a NullReferenceException even though instance r of EntityNReader is created and (verified to be) not null.
However, if I instantiate EntitiesN where it is declared in Database instead of within bindHandlers, the code compiles and everything works. The reason I don't just do this is that (subsequently) I would like to conditionally create readers/handlers inside of bindHandlers at the time the Database class is instantiated.
What is happening here? Link to actual code if necessary.
P.S. I am relatively new to programming, so I am open to hearing how an experience developer might design this component (especially if I am heading down the wrong path).
I realize your code was just samples, but I spotted this right off the bat...
if (supports[typeof(Entity1).Name]) { bindHandlers<Entity1Reader, Entity1>(Entities1, CamaDbType); }
if (supports[typeof(Entity2).Name]) { bindHandlers<Entity1Reader, Entity1>(Entities1, CamaDbType); }
Is it possible that you have a simple copy/paste mistake? Notice that Entities1 is passed in for both bindHandlers calls.

Lazy<T> and reflection-based initalization

I have a series of classes which initialize themselves when created based on using reflection to read a custom attribute on each property/field. The logic for all that is contained in an Initialize() method which they all call, which exists on the base class they inherit from.
I want to add usages of Lazy<T> to these classes, but I don't want to specify the function(s) in the constructor for each class, because they are "thin" constructors and the heavy lifting is in Initialize(). Conversely, I want to keep type-safety and such so I can't just provide a string of the code to use to initialize the Lazy<T>. The problem is that any usage which refers to the specific properties of the object can't be used in a static context.
Specifically, this is what I want my code to look like in an ideal world:
public class Data : Base
{
public Data(int ID) { Initalize(ID); }
[DataAttr("catId")] // This tells reflection how to initialize this field.
private int categoryID;
[LazyDataAttr((Data d) => new Category(d.categoryID))] // This would tell reflection how to create the Lazy<T> signature
private Lazy<Category> _category;
public Category Category { get { return _category.Value; } }
}
public abstract class Base
{
protected void Initalize(int ID)
{
// Use reflection to look up `ID` and populate all the fields correctly.
// This is where `categoryID` gets its initial value.
// *** This is where _category should be assigned the correct function to use ***
}
}
I would then access this the same way I would if Category were an automatic property (or an explicitly lazy loaded one with an _category == null check)
var data = new Data();
var cat = data.Category;
Is there any way I can pass the type information so that the compiler can check that new category(d.categoryID) is a valid function? It doesn't have to be via an Attribute, but it needs to be something I can see via Reflection and plug in to anything that has a Lazy<T> signature.
As an alternative, I will accept a way to do
private Lazy<Category> _category = (Data d) => new Category(d.categoryID);
This could either avoid reflection altogether, or use it to transform from this form to a form that Lazy<T> can handle.
I ended up using a solution inspired by #Servy's suggestion to get this working. The base class's Initialize() method now ends with:
protected void Initialize()
{
// Rest of code...
InitializeLazyVars();
/* We need do nothing here because instantiating the class object already set up default values. */
foreach (var fi in GetLazyFields())
{
if (fi.GetValue(this) == null)
throw new NotImplementedException("No initialization found for Lazy<T> " + fi.Name + " in class " + this.GetType());
}
}
InitializeLazyVars() is a virtual method that does nothing in the base class, but will need to be overridden in the child classes. If someone introduces a new Lazy<T> and doesn't add it to that method, we'll generate an exception any time we try to initialize the class, which means we'll catch it quickly. And there's only one place they need to be added, no matter how many constructors there are.

Design class chaining

I have a third party C# library for ldap operations. It does all operations on connection object as below:
LdapConnection connection = new LdapConnetion(Settings settings);
connection.Search(searchOU, filter,...);
which I feel is not readable. I want to write a wrapper around it so that I should be able to write code like below:
As I would like to have different Ldap classes like
public class AD: LdapServer { }
public class OpenLdap: LdapServer { }
and then
AD myldap = new AD(Settings settings);
myldap.Users.Search(searchOU, filter,...)
myldap.Users.Add(searchOU, filter,...)
myldap.Users.Delete(searchOU, filter,...)
I am thinking about Proxy design pattern, but things are not getting into my head about hot to go about it. What classes should I have etc.
Any help?
The solution posted above inherits from the LdapConnection. This is good if you want to maintain the inheritance chain, but I dont think that is necessary in your case. You simply want to customize and simplify the interface.
The proxy design pattern inherits from the underlying object so that the proxy object can be used anywhere that the underlying object is required, this is good if you want to "inject" extra functionality into the class without the clients of that class realising. I dont think this is your intention here?
The big problem with the solution posted above is that (because it inherits directly from LdapConnection) you can call search in two ways like so:
Settings settings = new Settings();
AD myAD = new AD(settings);
object results = myAD.Users.Search();
// OR
object results2 = myAD.Search();
As I'm sure you can see from the code, both of these call the exact same underlying method. But in my opinion, this is even more confusing to developers than just using the vanilla LdapConnection object. I would always be thinking "whats the difference between these seemingly identical methods??" Even worse, if you add some custom code inside the UsersWrapper Search method, you cannot always guarentee that it will be called. The possibility will always exist for a developer to call Search directly without going through the UsersWrapper.
Fowler in his book PoEAA defines a pattern called Gateway. This is a way to simplify and customize the interface to an external system or library.
public class AD
{
private LdapConnection ldapConn;
private UsersWrapper users;
public AD()
{
this.ldapConn = new LdapConnection(new Settings(/* configure settings here*/));
this.users = new UsersWrapper(this.ldapConn);
}
public UsersWrapper Users
{
get
{
return this.users;
}
}
public class UsersWrapper
{
private LdapConnection ldapConn;
public UsersWrapper(LdapConnection ldapConn)
{
this.ldapConn = ldapConn;
}
public object Search()
{
return this.ldapConn.Search();
}
public void Add(object something)
{
this.ldapConn.Add(something);
}
public void Delete(object something)
{
this.ldapConn.Delete(something);
}
}
}
This can then be used like so:
AD myAD = new AD();
object results = myAD.Users.Search();
Here you can see that the LdapConnection object is completly encapsulated inside the class and there is only one way to call each method. Even better, the setting up of the LdapConnection is also completely encapsulated. The code using this class doesn't have to worry about how to set it up. The settings are only defined in one place (in this class, instead of spread throughout your application).
The only disadvantage is that you loose the inheritance chain back to LdapConnection, but I dont think this is necessary in your case.
Ok, if you simply want to split the methods up into they objects that they act on (i.e. in your example add the .Users. before the method call) you can do something similar to this.. You'll need to get the method parameters and return types correct for your library, I've just used object here.
Is this the sort of thing you're looking for?
public class AD : LdapConnection
{
private UsersWrapper users;
public AD(Settings settings) : base(settings)
{
this.users = new UsersWrapper(this);
}
public UsersWrapper Users
{
get
{
return this.users;
}
}
public class UsersWrapper
{
private AD parent;
public UsersWrapper(AD parent)
{
this.parent = parent;
}
public object Search()
{
return this.parent.Search();
}
public void Add(object something)
{
this.parent.Add(something);
}
public void Delete(object something)
{
this.parent.Delete(something);
}
}
}
This can then be be used as follows:
Settings settings = new Settings();
AD myAD = new AD(settings);
object results = myAD.Users.Search();
Remember that this isn't strictly a "wrapper" because it actually inherits from the underlying class.

What methods should go in my DDD factory class?

I am struggling to understand what my factory class should do in my DDD project. Yes a factory should be used for creating objects, but what exactly should it be doing. Consider the following Factory Class:
public class ProductFactory
{
private static IProductRepository _repository;
public static Product CreateProduct()
{
return new Product();
}
public static Product CreateProduct()
{
//What else would go here?
}
public static Product GetProductById(int productId)
{
//Should i be making a direct call to the respoitory from here?
Greener.Domain.Product.Product p = _repository.GetProductById(productId);
return p;
}
}
Should i be making a direct call to the repository from within the factory?
How should i manage object creation when retriving data from a database?
What do i need to make this class complete, what other methods should i have?
Should i be using this class to create the Product object from the domain and repository from right?
Please help!
Should i be making a direct call to
the repository from within the
factory?
No, don't use a factory when your retrieving stuff, use a factory only when you are creating it for the first time.
How should i manage object creation
when retriving data from a database?
Pass that data into the factory, if it is required for the object's initial creation.
What do i need to make this class
complete, what other methods should i
have?
Many factories are not even individual classes, they are just methods that provide object creation. You could fold the factory method into another class, if you felt like it was just going to call a parameterless constructor.
Should i be using this class to create
the Product object from the domain and
repository from right?
The repository is for getting (in a sense creating) existing objects, the factory is for the first time you create an object.
Initially many factories won't do much except call a constructor. But once you start refactoring and/or creating larger object hierarchies, factories become more relevant.
Explanation and Example:
For instance, in the project I'm working on I have an excel processor base class and many subclasses implementing that base class. I use the factory to get the proper one, and then call methods on it, ignorant of which subclass was returned.(Note: I changed some variable names and gutted/altered a lot of code)
Processor base class:
public abstract class ExcelProcessor
{
public abstract Result Process(string ExcelFile);
}
One of the Processor subclasses:
public class CompanyAExcelProcessor : ExcelProcessor
{
public override Result Process(string ExcelFile)
{
//cool stuff
}
}
Factory:
public static ExcelProcessor CreateExcelProcessor(int CompanyId, int CurrentUserId)
{
CompanyEnum company = GetCompanyEnum(CompanyId);
switch (company)
{
case CompanyEnum.CompanyA:
return new CompanyAExcelProcessor();
case CompanyEnum.CompanyB:
return new CompanyBExcelProcessor();
case CompanyEnum.CompanyC:
return new CompanyCExcelProcessor(CurrentUserId);
//etc...
}
}
Usage:
ExcelProcessor processor = CreateExcelProcessor(12, 34);
processor.Process();
Be carefull, there are two reasons to instantiate a new object : Creating it and rehydrating it from the database.
The first case is handled by the factory. You can provide several methods to create an object on the factory.
Factory methods should return valid objects, so you can pass parameters to these methods to provides required information.
The factory method can also chose the actual type to instantiate based on parameters.
You should not mix this with rehydrating from the database. This kind of instantiation should take values from the datarow and instantiate the object with it. I usualy call this a data builder instead of a factory.
The main difference is that the factory will instantiate an object with a new identity while the databuilder will instantiate an object with an already existing identity.
What should go in your factory's Create method is whatever is necessary to put a brand spanking new object into a VALID state.
Now, for some objects that means you won't do anything except this:
public Product Create()
{
return new Product();
}
However, you may have business rules, default settings, or other requirements that you want to enforce when an object is created. In that case, you would put that logic in that method.
And that's part of the benefit of the Factory. You now have one and only one place where that special logic resides, and only one place where a new object gets created.
I personally would use the factory in couple of circumstances:
1) Something elsewhere governs what type of objects this factory returns (ie. it can return objects depending on circumstances. For example return a stub object when I am testing, return an actual implementation when I am not (this is obviously more of Inversion of Control / Dependency Injection issue - but if you do not want to add containers to your project just yet)).
2) I have quite complex objects that have containers, dependencies, other relation etc. and they need to be built carefully to avoid creating null or meaningless references. For example if I have a Schedule object I may need some start, end date fields set - if the logic for retrieving, figuring out these date is complex enough I may not want the calling class to know about it and just call the default factory method that created the schedule object.
Hope this helps.
In the example given above, I'm a little unclear on the distinction between your factory and the repository. I wonder if you shouldn't simply add CreateProduct as a method to the repository, and using DI to push the repository into code that needs it? If the factory isn't doing anything, etc...
Or if you just want it to act as a globally registered repository, perhaps something like:
public static IFooRepository Default {get;private set;}
public static void SetRepository(IFooRepository repository) {
Default = repository;
}
(in my mind it seems clearer to separate the "set" in this case, but you don't have to agree)
and have the callers use var product = YourFactory.Default.CreateProduct(); etc
#ThinkBeforeCoding - in #m4bwav's example, the factory is getting a valid ID from a helper method, but it's not creating a new record in a persistence layer anywhere. If, however, I'm using a database auto-generated identity column as my identities, it seems like a factory would have to call into the repository to do the initial object creation. Can you comment on which method is "correct"?
In the builder you can have any logic you need to inforce the invariants on your entites, a little example using Java as development language...
I have a User entity that has a username, a password and an email, all attributes required so I have:
public class User {
private String username;
private String password;
private String email:
/**
* #throws IllegalArgumentException if the username is null, the password is null or the
* email is null.
*/
public User(final String theUsername, final String thePassword, final String theEmail) {
Validate.notNull(theUsername);
Validate.notNull(thePassword);
Validate.notNull(theEmail);
this.username = theUsername;
this.password = thePassword;
this.email = theEmail;
}
// Getters / Setters / equal / hashCode / toString
}
and then I have the UserBuilder:
public class UserBuilder {
private String username;
private String password;
private String email;
public UserBuilder withUsername(final String theUsername) {
Validate.notNull(theUsername);
this.username = theUsername;
return this;
}
public UserBuilder withPassword(final String thePassword) {
Validate.notNull(thePassword);
this.password = thePassword;
return this;
}
public UserBuilder withEmail(final String theEmail) {
Validate.notNull(theEmail);
this.email = theEmail;
return this;
}
public User build() {
User user = new User(this.username, this.password, this.email);
return user;
}
}
And you can use the builder like this:
UserBuilder builder = new UserBuilder();
try {
User user = builder.withUsername("pmviva").withPassword("My Nifty Password").withEmail("pmviva#somehost.com").build();
} catch (IllegalArgument exception) {
// Tried to create the user with invalid arguments
}
The factory's solely purpose is th create valid instances of objects. In order not to duplicate creation and hydration code you can have your repositories to query a rowset from the database and delegate the creation of the object to a builder passing the rowset's data.
Hope this helps
Thanks
Pablo

Categories

Resources