make sure object only created by factory (C#)

2020-04-05 22:47发布

How do I make sure that a certain class is only instantiated by a factory and not by calling new directly?

EDIT: I need the factory to be a separate class (for dependency injection purposes) so I can't make it a static method of the class to be instantiated, and so I can't make new private.

8条回答
再贱就再见
2楼-- · 2020-04-05 23:12

You can make your concrete classes as nested private classes with public constructors inside your factory class - this way your factory can create them, others can't even see them. Anyway you return from factory some interface / abstract class, not concrete type. Of course you won't be able to cast your return type to a concrete type somewhere in a client code but first it's a sign of bad design, second you can always workaround it with more concrete interface / abstract class your nested private class inherits.

you can refer to the Eric Lippert's answer here (for a similar problem): Why Would I Ever Need to Use C# Nested Classes

查看更多
▲ chillily
3楼-- · 2020-04-05 23:15

Many people have mentioned using internal, but you can also make your constructors protected and derive a class that just has the static factory method in it. This doesn't prevent others from doing the same thing, but does a pretty good job at restricting direct access to your constructors.

查看更多
迷人小祖宗
4楼-- · 2020-04-05 23:18

Make the constructor internal and house the factory in the same assembly.

public MyClass
{
    internal MyClass()
    {
    }
}

in same assembly

public MyClassGenerator
{
    public static CreateMyClass()
    {
        return new MyClass();
    }
}

If the factory can't be in the same assembly or this method doesn't work for you, look to Dan's answer

查看更多
男人必须洒脱
5楼-- · 2020-04-05 23:18

I do not like to have the factory on the type itself especially if it is a domain object. Have it internal if you are having a separate class as factory (which I think you should). Use InternalVisible attribute if the factory is on the different assembly.

查看更多
狗以群分
6楼-- · 2020-04-05 23:21

Make its constructors private and supply the factory method as a static method on the class itself.

In most cases you can just make the constructors internal, allowing you to break the factory out into its own class - I've found it's often not worth trying to prevent my own team from using new to create instances within the class' assembly.

查看更多
戒情不戒烟
7楼-- · 2020-04-05 23:23

If the factory is in the same assembly and you only need protection against external assemblies instantiating the class, you can make the constructor internal. The only way I know to prevent this for all other classes (including those in the same assembly) is to make the instantiated class a nested private class of the factory and only expose it as an interface. If the class is its own factory (a static factory method), then you can make the constructor private, as others have mentioned.

查看更多
登录 后发表回答