Reputation: 4677
Is it possible to limit object creation to methods of specific class?
For exemple: I have a class Transaction, and I would like to limit it object creation to methods of any class that inherits from AbstractService or IService:
Allowed Scenario:
public class ServiceA : AbstractService (or IService)
{
public void MethodA()
{
var transaction = new Transaction();
}
public void MethodB()
{
var transaction = new Transaction();
}
}
Prohibited Scenario:
public class ServiceB
{
public void MethodA()
{
var transaction = new Transaction(); // cannot create
}
public void MethodB()
{
var transaction = new Transaction(); // cannot create
}
}
There is a access modifier or something else that I can mount that scenarios?
Upvotes: 3
Views: 651
Reputation: 54628
There is a access modifier or something else that I can mount that scenarios?
Yes there is something else that can "mount" that scenario, but it's a lot of work and abstraction for, in my opinion, very little reward. This requires returning an interface of the Transaction, not a concrete type. (I'm pretty sure this works, I haven't compiled it however).
public abstract class AbstractService
{
}
public interface IService
{
}
public interface ITransaction
{
}
public static class TransactionFactory
{
// created them as extensions, but you could remove *this*
public static ITransaction CreateTransaction(this AbstractService instance)
{
return new Transaction ();
}
public static ITransaction CreateTransaction(this IService instance)
{
return new Transaction ();
}
private class Transaction : ITransaction
{
public Transaction ()
{
}
}
}
As a side note, someone technically could pass in null, so it would be best to do additional checking of the method parameters (however, that would be a runtime issue instead of a compile time issue).
If you wanted compile time checking I think you could do...
public interface ITransactionFactory { }
public abstract class AbstractService : ITransactionFactory { }
public interface IService : ITransactionFactory { }
public static class TransactionFactory<T>
where T : ITransactionFactory
{
public static ITransaction CreateTransaction(this T instance)
{
return new Transaction ();
}
// ....
Not quite sure if the second one works
Upvotes: 2
Reputation: 3520
Maybe I'm misunderstanding what you're trying to do, but it seems like this should do the trick:
public abstract class AbstractService : IService
{
protected class Transaction
{
}
}
public class ServiceA : AbstractService
{
public void MethodA()
{
var transaction = new Transaction();
}
public void MethodB()
{
var transaction = new Transaction();
}
}
public class ServiceB
{
public void MethodA()
{
var transaction = new Transaction(); // cannot create
}
public void MethodB()
{
var transaction = new Transaction(); // cannot create
}
}
internal interface IService
{
}
If you want anyone else to be able to use the Transaction
, you'll need to have it implement some public interface or inherit it from another public class, but you can now ensure that no one else can create a Transaction object.
Upvotes: 2
Reputation: 136114
The short answer is no, there is no access modifier which says "This object can only be constructed from a class which implements a specific interface".
You could code your way round this limitation, but its far from clean/foolproof.
public class Transaction
{
private Transaction(){} // private important!
public static Transaction Create(object creator)
{
if(creator is IService)
return new Transaction();
throw new InvalidOperationException();
}
}
public class ServiceA : IService
{
public void MethodA()
{
var transaction = Transaction.Create(this); // works
}
}
public class ServiceB
{
public void MethodA()
{
var transaction = Transaction.Create(this); // fails
}
}
It should be obvious how easily circumventable the above is. I suspect you have an XY Problem and you think this was the way to solve it.
Upvotes: 2