简体   繁体   中英

c# inheritance hide methods from only one derived class

I have a retail WebSite built with MVC. Calls are made to a REST WebAPI service to provide basic CRUD operations. I want to create a shared DLL that I can reference between the website and the API. That DLL would contain the models (that match my DB table structure) and the code to perform the basic CRUD operations. This way I wont have to reference my database code in the WebAPI at all. I can do this just fine. My question becomes, is there anyway to hide the methods from the retail WebSite, while still making them visible to the API?

What I'm currently doing (which doesnt work) is creating a class in the WebSite that inherits from a class in the DLL. That gets me the model from the DLL, however it also would technically allow me to call the methods to interact with the database.

Here's an example:

In the DLL

    public class Account {
        public int AccountId { get; set; }
    }

    public int RetrieveAccountId {
        // Hit the database to retrieve the current account id...
    }

In the Retail MVC WebSite

    public class mmAccount : Account {
    }

Now, in the retail mvc site, I can say mmAccount.AccountId

In the Web API, I can call the function RetrieveAccountId directly like this:

    Account account = new Account();
    account.RetrieveAccountId();

The problem is, I can also technically do this through mmAccount (derived from Account) in the WebSite. Is there anyway I can hide that method only from the WebSite?

You could mark the methods internal and use the internalsVisibleTo Attribute

Though that feels a bit hacky. Personally I have a service layer in between - the website NEVER directly sees the database models; it only ever receives DTO objects which are populated by some form of service. This way the Web site doesn't care if your underlying database structure changes, and never needs to know what the underlying 'ID' of an entity is...

That depends - if you want to allow this inheritance selectively, you may instead wish to use interfaces and a manager or factory to supply the instances to the WebAPI version, with interfaces that do not allow the functionality you don't want.
If you do not need to inherit the .RetreiveAccountId() function elsewhere, you can make it either internal or (with C# 7.2) private protected . Internal will allow other classes in the same assembly to use the method, and private protected will let derived classes in the same assembly (but not derived classes in a different assembly) use the function.

To hide a method in the child class, you have to redefine it's functionality in the child class using the new keyword.

public class mmAccount : Account {
    public new int RetrieveAccountId {
        throw new WhatDoYouThinkYouAreDoingException("You are not allowed!");
    }
}

Any call to mmAccount.RetrieveAccountId() would be routed through this new method. The downside of this is that the following would still give the original return:

mmAccount mAcc = new mmAccount();
Account acc = mAcc as Account;
int id = acc.RetrieveAccountId();

To truly fix this, you would have to change something about the parent class aswell (using a virtual method and overriding it for example)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM